Almost two years since the last post it’s time to refresh my website and write about something else. Most of these two years have been spent on my first true and mid-sized open source project along with two friends: Lavagna.
Lavagna is “an open-source issue/project management tool designed for small teams. Lightweight, pure Java, easy to install, easy to use.” This project allowed me to explore many areas and I’d like to write some posts about the most interesting topics because I find them useful to everybody who wants to start an open source project.
The first post is about wrapping a Spring application in a Windows Service, this is must have if you want to deploy your project also on Windows and surprisingly I didn’t find many articles about it.
The first thing to do when a project reaches the “ready to be shown to the world” stage is to offer as many ways as you can to try your software. Someone may like to download the source, look at it, build and run but the best way is to provide something easy to setup so you can use the application within minutes. With Lavagna we provide a standard package or a Docker container. I personally prefer Docker because with a simple docker pull digitalfondue/lavagna you find yourself with the server up and running without effort but I must admit that not everybody has Docker ready on his machine. Having said that many people still like a conventional package and, when using it under Windows, the best way to set it up is using a Windows Service. Lavagna is a Spring application that by default runs in a self contained Jetty server and it took me too much trying to figure out what wrapper I had to use to run it as a Windows Service.
Wrapping everything up
The first thing to do is to go to the winsw binaries site and grab the latest package. Unzip the archive and rename winsw.exe to your project’s name, like in my case lavagna.exe; this is the main executable that acts as a Windows Service and wraps your application. The next thing to do is to add some configuration to handle correctly the executable on various Windows versions, in order to do so create a file named lavagna.exe.config that contains the following XML:
<configuration> <startup> <supportedRuntime version="v2.0.50727" /> <supportedRuntime version="v4.0" /> </startup> <runtime> <generatePublisherEvidence enabled="false"/> </runtime> </configuration>
The real configuration must be written in another file that has the same name as the executable but ends with a .xml, like lavagna.xml:
<service> <id>Lavagna</id> <name>Lavagna</name> <description>This service runs Lavagna, an open-source issue/project management tool designed for small teams.</description> <executable>java</executable> <arguments>-Ddatasource.dialect=HSQLDB -Ddatasource.url=jdbc:hsqldb:mem:lavagna -Ddatasource.username=sa -Ddatasource.password= -Dspring.profiles.active=dev -jar ..\..\lavagna\lavagna-jetty-console.war</arguments> <logmode>rotate</logmode> <stopparentprocessfirst>true</stopparentprocessfirst> </service>
As you can see everything is pretty straightforward:
|id||Windows Service id, useful for a net start / stop.|
|name||Windows Service name, appears in the Services GUI.|
|description||Windows Service description, appears in the Services GUI.|
|executable||Executable to invoke, usually you just have to leave it set to java.|
|arguments||This is the important part, put here everything you need to run your application here.|
Now you have everything you need to run your Java application as a Windows Service. It’s very easy but as I mentioned early I never found a simple tutorial on how to achieve it.
If you wish you can also include these two .bat to help the final user install and uninstall your service.
@echo off rem lavagna windows service installer %~dp0/lavagna.exe install net start Lavagna
@echo off rem lavagna windows service uninstaller net stop Lavagna %~dp0/lavagna.exe uninstall