Está en la página 1de 7

InstallingaJavaApplicationasaWindowsService

EverwonderedhowtoinstallaJavaapplicationasaWindowsservice?Thisarticleshows
youhowtodoit.

by
BozhidarBozhanov

Jun.27,16JavaZone
Like(18)
Save
11.03kViews
LearnmoreaboutKotlin,anewprogramminglanguagedesignedtosolveproblemsthatsoftwaredevelopers
faceeverydaybroughttoyouinpartnershipwithJetBrains.
Itsoundslikesomethingyoudneverneed,butsometimes,whenyoudistributeendusersoftware,youmay
needtoinstallajavaprogramasaWindowsservice.IhadtodoitbecauseIdevelopedatoolforcivilservants
toautomaticallyconvertandpushtheirExcelfilestotheopendataportalofmycountry.Thetoolhastorun
periodically,soitsaprimecandidateforaservice(whichwouldmaketheuploadpossibleevenifthecivil
servantforgetsaboutthistaskaltogether,andbesides,repetitivemanualuploadisawasteoftime).
EventhoughtherearenumerouspostsandStackOverflowanswersonthetopic,itstilltookmealotoftime
becauseofminorcaveatsandoneimportantprerequisitethatfewpeopleseemedtohavehavingabundled
JRE,sothatnobodyhastodownloadandinstallaJRE(wouldcomplicatetheinstallationprocessunnecessarily,
andthetargetaudienceisnotnecessarilytechsavvy).
So,withmavenprojectwithjarpackaging,Ifirstthoughtofpackagingan.exe(withlaunch4j)andthen
registeringitasaservice.Theproblemwiththatisthatthejavaprogramusesascheduledexecutor,soitnever
exits,whichmakesstartingitasaprocessimpossible.
SoIhadtodaemonizeit,usingcommonsdaemonprocrun.Beforedoingthat,Ihadtoassembleevery
componentneededintoasingletargetfolderthefatjar(includingalldependencies),theJRE,thecommons
daemonbinaries,andtheconfigfile.
Youcanseethefullmavenfilehere.Therelevantbitsare(where${installer.dir}is
${project.basedir}/target/installer}):
<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>mavencompilerplugin</artifactId>

<version>2.3.2</version>

<configuration>

<source>1.8</source>

<target>1.8</target>

</configuration>

</plugin>

<plugin>

<artifactId>mavenassemblyplugin</artifactId>

<executions>

<execution>

<id>assembly</id>

<phase>package</phase>

<goals>

<goal>single</goal>

</goals>

<configuration>

<descriptorRefs>

<descriptorRef>jarwithdependencies</descriptorRef>

</descriptorRefs>

<finalName>opendatackanpusher</finalName>

<appendAssemblyId>false</appendAssemblyId>

</configuration>

</execution>

</executions>

</plugin>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>mavenantrunplugin</artifactId>

<version>1.7</version>

<executions>

<execution>

<id>defaultcli</id>

<phase>package</phase>

<goals>

<goal>run</goal>

</goals>

<configuration>

<target>

<copytodir="${installer.dir}/jre1.8.0_91">

<filesetdir="${project.basedir}/jre1.8.0_91"/>

</copy>

<copytodir="${installer.dir}/commonsdaemon">

<filesetdir="${project.basedir}/commonsdaemon"/>

</copy>

<copyfile="${project.build.directory}/opendatackanpusher.jar"
todir="${installer.dir}"/>

<copyfile="${project.basedir}/install.bat"todir="${installer.dir}"
/>

<copyfile="${project.basedir}/uninstall.bat"
todir="${installer.dir}"/>

<copyfile="${project.basedir}/config/pusher.yml"
todir="${installer.dir}"/>

<copyfile="${project.basedir}/LICENSE"todir="${installer.dir}"/>

</target>

</configuration>

</execution>

</executions>

</plugin>
Youwillnoticetheinstaller.batanduninstaller.batwhicharethefilesthatusecommonsdaemontomanagethe
service.Theinstallercreatestheservice.Commonsdaemonhasthreemodes:.exe(whichallowsyoutowrap
anarbitraryexecutable),Java(whichislike.exe,butforjavaapplications)andJVM(whichrunsthejava
applicationinthesameprocessIdontknowhowexactlythough).
Icoulduseallthreeoptions(includingthelaunch4jcreated.exe),buttheJVMallowsyoutohaveadesignated
methodtocontrolyourrunningapplication.TheStartClass/StartMethod/StopClass/StopMethodparametersare
forthat.Heresthewholeinstaller.bat:
commonsdaemon\prunsrv//IS//OpenDataPusherDisplayName="OpenDataPusher"
Description="OpenDataPusher"^

Install="%cd%\commonsdaemon\prunsrv.exe"
Jvm="%cd%\jre1.8.0_91\bin\client\jvm.dll"StartMode=jvmStopMode=jvm^

Startup=autoStartClass=bg.government.opendatapusher.Pusher
StopClass=bg.government.opendatapusher.Pusher^

StartParams=startStopParams=stopStartMethod=windowsService
StopMethod=windowsService^

Classpath="%cd%\opendatackanpusher.jar"LogLevel=DEBUG^LogPath="%cd%\logs"
LogPrefix=procrun.log^

StdOutput="%cd%\logs\stdout.log"StdError="%cd%\logs\stderr.log"

commonsdaemon\prunsrv//ES//OpenDataPusher
Afewclarifications:
TheJVMparameterpointstotheJVM.dll(tobehonest,Imnotsureifthiswillworkifthereisnootherjava
installationonthemachineitshould)
TheStartClass/StartMethod/StopClass/StopMethodpointtoadesignatedmethodforcontrollingtherunning
application.Inthiscase,startingwouldjustcallthemainmethod,andstoppingwouldshutdownthe

scheduledexecutor,sothattheapplicationcanexit
Theclasspathparameterpointstothefatjar
Using%cd%isriskyfordeterminingthepathtothecurrentdirectory,butsincetheenduserswillalwaysbe
startingitfromthedirectorywhereitresides,itssafeinthiscase.
ThewindowsServicelookslikethat:
publicstaticvoidwindowsService(Stringargs[])throwsException{

Stringcmd="start";

if(args.length>0){

cmd=args[0];

if("start".equals(cmd)){

Pusher.main(newString[]{});

}else{

executor.shutdownNow();

System.exit(0);

}
Oneimportantnotehereisthe32bit/64bitproblemyoumayhave.Thatswhyitssafertobundlea32bitJRE
andusethe32bit(default)prunsrv.exe.
IthenhadaninstallerfolderwithJREandcommonsdaemonfoldersandtwobatfilesandonefatjar.Icould
thenpackagethatasaselfextractablearchiveanddistributeit(withamanual,ofcourse).IlookedintoIzPack
aswell,butcouldntfindhowtobundleaJRE(maybeyoucan).
ThatsaprettynichescenariousuallywedevelopfordeployingtoaLinuxserver,butprovidinglocaltoolsfor

abigorganizationusingJavamaybeneededeverynowandthen.Inmycasethelongrunningpartwasa
scheduledexecutor,butitcanalsorunajettyservicethatservesawebinterface.Whywoulditdothat,instead
ofprovidingaURLincaseswhereaccesstothelocalmachinematters.Itcanevenbeadistributedsearch
engine(likethat)oranotherp2psoftwarethatyouwanttowriteinJava.
TheJavaZoneisbroughttoyouinpartnershipwithJetBrains.Discoverhowpowerfulstaticcodeanalysisand
ergonomicdesignmakedevelopmentnotonlyproductivebutalsoanenjoyableexperience.

También podría gustarte