Create a Windows Service for Java using WinRun4J

The following is a quick tutorial on a creating a windows service in Java using WinRun4J.

The first step is to download WinRun4J.

Now unzip it into any folder, create a new directory called service and copy over the following files from the download:

  • WinRun4Jc.exe
  • service.ini
  • WinRun4J.jar
  • WinRun4jTest.jar

Now rename WinRun4Jc.exe to service.exe and you should have a folder that looks like this:

Now we need a command prompt with Administrator priveleges. This can be created in Vista/Windows7 by going Start->All Programs->Accessories, right-click on Command Prompt and select Run as Administrator:

Now change into the service directory you created above:

To register the service with the Windows Service Control Manager (SCM), run the following command:

C:\downloads\service>service.exe --WinRun4J:RegisterService

Now if you start up the Windows service viewer you should see the WinRun4J test service:

You can start/stop the service using the service viewer.

The code listing for the service implementation is as follows:

package org.boris.winrun4j.test;

import org.boris.winrun4j.EventLog;
import org.boris.winrun4j.Service;
import org.boris.winrun4j.ServiceException;

/**
 * A basic service.
 */
public class ServiceTest implements Service {
    private int returnCode = 0;
    private volatile boolean shutdown = false;

    public int doRequest(int request) throws ServiceException {
        switch (request) {
        case SERVICE_CONTROL_STOP:
        case SERVICE_CONTROL_SHUTDOWN:
            shutdown = true;
            break;
        }
        return 0;
    }

    public int getControlsAccepted() {
        return SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    }

    public String getName() {
        return "WinRun4J Test Service";
    }

    public String getDescription() {
        return "An example service using WinRun4J.";
    }

    public int main(String[] args) throws ServiceException {
        int count = 0;
        while (!shutdown) {
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
            }

            if (++count % 10 == 0)
                EventLog.report("WinRun4J Test Service", EventLog.INFORMATION,
                        "Ping");
        }

        return returnCode;
    }
}

The main method is called from the WinRun4J launcher when the service is required to run. This method should not return until the service is shutdown.

The doRequest method is called by the WinRun4J launcher on a separate thread (i.e. the service control thread). This method should modify the state of the application based on the request type passed in. In the example we just modify the shutdown flag.

The getName and getDescription methods are called when the service is registered. These values appear in the service viewer.

The example service simply logs to the windows event log every minute.

Advertisements

28 Responses to Create a Windows Service for Java using WinRun4J

  1. Rogerio says:

    Hello.
    Thanks for this product.
    Could I make a sugestion?
    It would be great to have a feature that could restart the application, without stopping the exe. It would stop only the jvm, and relaunch it…
    Thanks!

  2. poidasmith says:

    Hi,
    What would be the benefit of stopping only the jvm? Presumably all your state would live in the jvm anyway?
    Thanks

    • Rogerio says:

      If I could programmatically restart the jvm, I could detect configuration changes (or even jar updates), and restart the program, without the windows service restarting.
      But if I could restart the service internally, that would be good as well.
      Thanks!

    • Rogerio says:

      I forgot, restarting only the jvm would be beneficial to exe’s too, like firefox restart after updating addons. The exe would still be running, but the java application would close and return updated.
      I already do that using the Java Wrapper by Tanuki Software, but my software will be commercial, and the license cost is prohibitive.
      Thanks!

  3. illya says:

    Thanks for the product…

    I’m having some issues, I don’t know if this is the best place to ask for help….but anyway…

    It seems I cannot configure sending arguments to a service. I have the service implementing Service and have some System.out of the parameters args in the method
    public int main(String[] args) throws ServiceException

    But it seems that the args are always null.

    Thanks

    • poidasmith says:

      Hi,

      Thanks for the feedback. There is an issue in the launcher where service parameters aren’t passed correctly. There will be a new version ready very soon that will address this.

      Thanks.

    • poidasmith says:

      Hi,

      There is a new release of WinRun4J (0.3.2) that addresses this issue.

      Regards.

      • mmastrangelo says:

        I am running 0.3.3, and can’t seem to get an argument passed into my serviceMain method (in a subclass of AbstractService). I have a single argument defined in my ini file in the “arg.0” property.

        The argument appears to be recognized when the service starts:

        [info] Program Args
        [info] arg.0=C:/temp/

        …however I get an ArrayIndexOutOfBounds exception when I try to read element 0 in the args array.

        Any help would be appreciated!

  4. illya says:

    Thanks a lot, I’ll check it

  5. Rogerio says:

    Hello again!
    It seems I cannot set the working.directory because it fails to register the service with: [err] Could not find service class
    I´m trying to set it to parent (..).
    If I move the exe and ini to the parent dir it works, if I change the classpath’s to include “../”, it works too…
    Shouldn´t it work relative to the working dir?
    Thanks!

    • poidasmith says:

      Hi,

      The launcher does use the working directory when generating the classpath unless it has not been set in the INI (in which case it uses the directory of the INI file as the working directory).

      When you have logging level set to info do you see a line that says:

      [info] Working directory set to:

      Regards.

      • Rogerio says:

        Yes, I had set int the INI: working.directory=..
        I am in path: C:\semasp\winrun4j
        I see a line: [info] Working directory set to: C:\semasp
        The classpath is correct: classpath.1=winrun4j/*.jar
        classpath.2=bin/*.jar
        But the bug is:
        If I call the executable without args, the classpath does get expanded:
        [info] Expanding Classpath: winrun4j/service.jar
        [info] Expanding Classpath: winrun4j/WinRun4J.jar
        [info] Expanding Classpath: bin/*.jar
        [info] Expanding Classpath: C:\semasp\bin/sitefweb_comunicserver.jar
        [info] Expanding Classpath: C:\semasp\bin/sitefweb_infra.jar
        [info] Expanding Classpath: C:\semasp\bin/sitefweb_profile.jar
        [info] Expanding Classpath: C:\semasp\bin/sitefweb_rmiserver.jar
        [info] Expanding Classpath: bin/lib/*.jar
        [info] Expanding Classpath: C:\semasp\bin\lib/drivers_jdbc.jar
        [info] Expanding Classpath: C:\semasp\bin\lib/framework_log.jar
        [info] Generated Classpath: C:\semasp\winrun4j\service.jar; (…)

        BUT if I call it with –WinRun4J:RegisterService, I get:
        [info] Expanding Classpath: winrun4j/service.jar
        [info] Expanding Classpath: winrun4j/WinRun4J.jar
        [info] Expanding Classpath: bin/*.jar
        [info] Expanding Classpath: bin/lib/*.jar
        [info] Generated Classpath: (empty line)

        [err] Could not find service class

        That´s it.
        Thank you for your attention.

      • Rogerio says:

        In my example, I tried to include winrun4j/service.jar and winrun4j/WinRun4J.jar directly, instead of winrun4j/*.jar, but it is no different.
        Only when trying to register the service…

      • poidasmith says:

        OK, yes, I can see the problem now – the launcher is not setting the working directory when the register service command is specified. Thanks for finding that one!

        I will get a fix out shortly for this.

        I think in the future version I will move the name and description to the INI file so it doesn’t need to startup the VM just to get these two bits of information when registering the service…

      • poidasmith says:

        BTW in the short term you could add fixed paths eg

        classpath.1=c:\semasp\bin\*.jar

        or even use evironment variables: APP_HOME=c:\semasp

        then
        classpath.1=%APP_HOME%\bin\*.jar

      • Rogerio says:

        Ok, Thank you for your great work!
        Humm, great idea moving the name and description to the INI! It was kind wierd setting the service params in two different places.
        And if I need to change the name or description (to several customers), I don´t need to recompile! It is very good!
        Thanks again…

  6. Rainer says:

    Hi,
    i’m running version 0.3.2 and try to start my osgi environment as a windows service.
    there is still the problem, that the args aren’t passed to the main method of the class implementing Service. The length of the array is correct but the values are empty.
    For when is the next release planed?
    Thanks Rainer

  7. Dusan says:

    Hi,
    Thank you for this product. I really like it. At the moment I am using it to run my java program as service. I have following question / suggestion. After I have installed my service with: service.exe –WinRun4J:RegisterService Is there a way how to start this installed service from command prompt with something like service.exe –WinRun4J:StartService ?
    Thanks

    • poidasmith says:

      Hi,

      There isn’t a built in command to start/stop the service but you can use the “net” command. ie.

      net start [service name]
      net stop [service name]

      See here for more details: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/net_start.mspx?pf=true

      Regards,
      Peter

      • Dusan says:

        Excellent!
        Thank you Peter, that’s exactly what I need.
        Dusan

      • Dusan says:

        Hello again,

        I am happily using this product, but I have encoutered following problem. I have installed my service under administrator account to start automatically with windows (using Local system account). It works perfectly, service gets started with windows and is running perfectly. When I log in to the windows as administrator the service is still running. But when I log off as administrator and try to log in as different user the service will stop. In the Event viewer in System Log I have found message that service terminated unexpectedly with no more details. Has anybody else experienced something simillar ?

        Regards,

        Dusan

  8. Dusan says:

    Hi,

    I have found solution for the problem – in case somebody else needs it.
    Run JVM with parameter –Xrs (reduce OS signals)
    Add following line in service.ini file.

    vmarg.1=-Xrs

    Regards,

    Dusan

  9. Jim says:

    hello everyone,
    i am using this programme for the first time and although very helpful ive come across a trouble.Although the application that im trying to wrap so as to be executed as a win service functions great when i try it as a service fails because cant find an xml configuration file.If there is any suggestions on how to achieve it (some var in the service.ini or sth) or whats going wrong would be cheerfully aceptable.

    Thanks in advance fellas
    Jim

  10. Sam says:

    Hi
    I am trying to generate exe file and I am adding a jar file to it . How should I add jar file to my class path .

    As of now
    I have added classpath.1 = *.jar
    problem is that when I run exe . I see genreated classpath is empty and it give error . please reply

  11. Sheldon M says:

    The script terminates after printing “[info] Registering natives for FFI class” in the log, no errors or reason to why it terminated, please help!!!

    • Mat B says:

      I also get the termination issues and the last thing in the log is : Registering natives for FFI class.
      Using Windows 7 64 bit. Pretty sure I have the correct exe.

  12. nilesh says:

    Thanks for all this.I used it & it creates the exe which works fine but I have problem that it does not show the service in windows service folder.

%d bloggers like this: