Skip to main content

winsw: Windows service wrapper in less restrictive license

Posted by kohsuke on September 29, 2008 at 6:41 PM PDT

I reported earlier that Hudson can now install itself as a Windows service,
and behind this technology is the reusable Windows service wrapper code I wrote, which is separately reusable and available in the "winsw" project.

Why?

Now, I think the first question that people would ask is, why another, when there's Java Service Wrapper project already available. The main reason for writing my own was the license — Java Service Wrapper project is in GPL (so that they can sell their commercial version in a different license), and that made it difficult for Hudson (which is under the MIT license) to use it.

Functionality-wise, there's really not much that's worth noting; the problem of wrapping a process as a Windows service is so well defined that there aren't really any room for substantial innovation. You basically write a configuration file specifying how you'd like your process to be launched, and we provide programmatic means to install/uninstall/start/stop services. Another notable different is that winsw can host any executable, whereas Java Service Wrapper can only host Java apps. Whether you like this or not depends on your taste, so I wouldn't claim mine is better. It's just different.

Usage

You write the configuration file that defines your service. This is the one I use for Hudson:

<br /><service><br />  <id>hudson</id><br />  <name>Hudson</name><br />  <description>This service runs Hudson continous integration system.</description><br />  <env name="HUDSON_HOME" value="%BASE%"/><br />  <executable>java</executable><br />  <arguments>-Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\hudson.war" --httpPort=8080</arguments><br /></service><br />

You'll rename winsw.exe into something like hudson.exe, then you put this XML file as hudson.xml.
The executable locates the configuration file via this file name convention. You can then install the service like:

hudson.exe install

... and you can use the exit code from these processes to determine whether the operation was successful. There are other commands to perform other operations, like uninstall.

This project is available on Kenai (which is the new forge Sun is doing), along with a complete documentation, the source code, and the binary.

Implementation highlight

The code is implemented in C# (which makes it super-easy to implement something like this, compared to doing so in C++.) I use a java.lang.reflect.Proxy-like technique so that I can perform WMI operations elegantly. It's been a while I've done .NET development, so this was fun. C# got several really nifty language features that make the code terse (which I'd love to see in Java), but OTOH the library still sucks — for example, the Proxy capability is not a part of the core library.

On a related note, projects like com4j and JNA make it probably possible to do this entirely in Java. I think this would be an interesting hobby project for someone, so that people can avoid forking processes, which is always awkward.

Related Topics >>

Comments

Where can I find the winsw

Where can I find the winsw source code and documentation? The kenai.com website seems to be down.
I'd like to debug winsw as since a couple of days my hudson service fails to start for no apparent reason. The hudson service stops after a couple of seconds with no error message and no log file being generated.

Ooops, sorry for the latest

Ooops, sorry for the latest post. The kenai.com server was only temporarily not reachable from our corporate network.
Today I could download the source and could also track down the error. The winsw service failed to start because of an unhandled Win32Exception ("The event log file is full") when trying to write the first event log entry. My "Application" event log was configured with a max size of 512 KB and deletion of records older than 7 days, but it was completely filled with entries which were only 3 days old.
After clearing the "Application" event log, the hudson service started again.

mzehrer &mash; I think it's relatively easy to make a launcher part pluggable so that you don't have to write a lengthy "-classpath" option. I just didn't need it for Hudson because it doesn't have any classpath :-)

boerkel -- Ah, I didn't know that. I guess I'd still have to write the install/uninstall part, no? As for .NET, I think it's available in almost all the modern Windows to the point that it's a non-issue. Besides, it's just so much more productive to do it in .NET than to do this in the plain C++.

NIce feature. But why make .NET a requirement for a Java project? BTW, JNA already bundles a Win32 service implementation in Java.

Nice project. But I miss the Java specific features for classpath configuration that Java Service Wrapper has.

jan_bar -- Thanks for the fix. I incorporated that into 1.255.

thomasd &mash; Aha! Yeah, I guess with a bit more wrapping this would be enough for me. Thanks for the tip.

boerkel &madsh; Thanks. I think what I should start doing maybe is to ask if something already exists before I start implementing...

Thanks for winsv. There is one bug in hudson.xml default configuration. Add -Xrs to prevent JVM termination on CTRL_LOGOFF_EVENT. Otherwise winstone will terminate on logoff.

Hi, cool Stuff :) Btw. .Net offers a Dynamic Proxy Feature in the Standard Library. System.Runtime.Remoting.Proxies.RealProxy; Although it is intended for remote Proxies you can also use it to implement regular dynamic proxies - so you don't have to generate IL Code by hand :) Have a look at this: http://www.tutorials.de/forum/net-application-und-service-design/249443-... Best regards, Tom

Install/uninstall is included in the JNA Win32 service implementation.