Build windows service from java application with procrun


Recently, I needed to adjust a Java application to be able to run as a Windows service which is the Windows equivalent to a Unix daemon. There are several libraries available for this kind of task and after some reading, I chose Apache procrun which turned out to be a good choice. The configuration was less painful than expected and the tool seems quite powerful, due to a large set of configuration options. Also, building a Windows service or a Unix daemon should not make much of a difference. I used a 64bit Windows 7 and 32bit Java 7 JVM for this tutorial.

Everything you need to know about procrun really is on the page that is linked above. There even is a basic tutorial. However, the documentation is not overly verbose and it took me some time to get everything up and running, so I think a more verbose basic tutorial will not hurt.

To begin with, you need a Java application. You can built a service from more or less any application and here is a simple class, SomeService with some artifical behaviour:

package com.wordpress.joerglenhard.procrun.demo;

public class SomeService {

    private static boolean stop = false;

    public static void start(String[] args) {
        System.out.println("start");
        while (!stop) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            System.out.println("running");
        }
    }

    public static void stop(String[] args) {
        System.out.println("stop");
        stop = true;
    }

    public static void main(String[] args) {
        if ("start".equals(args[0])) {
            start(args);
        } else if ("stop".equals(args[0])) {
            stop(args);
        }
    }

}

The application acknowledges the call of the start method and then keeps on printing the String “running” every second until it is stopped through the stop method.
Actually, the normal main method and the other two static methods are alternatives for starting and stopping the service. I found both ways useful and will get to that later.

Next, you need to build an executable from this class. For Windows that would be the usual .exe, but an executable jar file is just as fine. I used a jar file and though the contents are very basic, for completeness, here is the MANIFEST.MF:

Manifest-Version: 1.0
Class-Path: .
Main-Class: com.wordpress.joerglenhard.procrun.demo.SomeService

Now, you need procrun to turn that into a Windows service. Download it from the procrun download page and unpack whatever you chose to download. In my case, this was version 1.0.10 of the Windows binaries and the essential part in the archive is prunsrv.exe, the procrun service application which is responsible for installing and removing the service. prunmgr.exe is also an extremly useful application that provides a GUI to set everything you can configure via batch scripts.

The difficult part now is to install the service. This can be done by a call of prunsrv.exe with appropriate options. There are quite some options you can / have to use, so this is best packaged as a batch script which I called installService.bat:

set SERVICE_NAME=TestService
set PR_INSTALL=C:\workspaces\blog\procrun-demo\prunsrv.exe

REM Service log configuration
set PR_LOGPREFIX=%SERVICE_NAME%
set PR_LOGPATH=c:\logs
set PR_STDOUTPUT=c:\logs\stdout.txt
set PR_STDERROR=c:\logs\stderr.txt
set PR_LOGLEVEL=Error

REM Path to java installation
set PR_JVM=C:\Program Files (x86)\Java\jre7\bin\client\jvm.dll
set PR_CLASSPATH=someservice.jar

REM Startup configuration
set PR_STARTUP=auto
set PR_STARTMODE=jvm
set PR_STARTCLASS=com.wordpress.joerglenhard.procrun.demo.SomeService
set PR_STARTMETHOD=start

REM Shutdown configuration
set PR_STOPMODE=jvm
set PR_STOPCLASS=com.wordpress.joerglenhard.procrun.demo.SomeService
set PR_STOPMETHOD=stop

REM JVM configuration
set PR_JVMMS=256
set PR_JVMMX=1024
set PR_JVMSS=4000
set PR_JVMOPTIONS=-Duser.language=DE;-Duser.region=de
REM Install servic prunsrv.exe //IS//%SERVICE_NAME%

Open the command prompt and move to the directory where the script is located. The script modifies the registry, so it needs to have administrator privileges to execute successfully. The first line sets the service name which determines its registry key. Next, you need to set the path to prunsrv.exe. On that note, here is a lesson that took me some time to learn: If you use (correct) relative paths to files in the installation script, the service will install correctly and it will run fine in debugging mode. It will however fail when run normally with any administrative tooling you have. Be it the usual Windows management console (Computer -> Manage -> Services and Applications -> TestService) or prunmgr.exe. Generally, you should use absolute paths with procrun. Interestingly, there is one exception to this rule: the jar file you use as classpath. Here, the relative path worked out fine for me. Another lesson, I found on stackoverflow, is that you must not use white spaces in the service name.

But back to the script: Lines 5 – 9 set the logging behaviour This needs to be adjusted to proper paths of the system. The same applies to line 12 which needs to point to a jvm, on my system this is a client jvm. This is required, because the service here is set to run in jvm mode (line 17). In java mode, the JAVA_HOME environment variable is used to resolve the jvm location. The difference between the modes essentially is that the jvm mode starts the service in-process while the other modes (java or exe) use a separate one.

Lines 16 – 19 and 22 – 24 reference the class that allows to start and stop the service which is of course the only class we have here. Furthermore, the methods to be invoked on startup and shutdown are set. You can set the method arguments as well using PR_STARTPARAM or PR_STOPPARAM, but this is required for the methods used here. Had I used the normal main method, the setting of the program arguments would have been required. Lines 27 – 30 set the memory settings of the jvm and last but not least, Line 33 installs the service.

Now, you can use prunsrv.exe to run the service in debugging mode (you can do that without administrator privileges) which uses the current command prompt as output:

> start prunsrv.exe //TS//TestService

This fires up a new window and if you hit CTRL+C to stop the service, you should see something like the following before the window closes:

You might wonder why the service outputs one more “running” after the stop method was invoked. Start and stop are called from different threads, so there can be race conditions. I wanted to keep the service code simple and did not use any synchronization. That’s fine for a trivial example, but not for production code, of course.

Finally, in case you don’t want to keep that service on your system, uninstallation is pretty easy. Simply call (with administrator privileges):

> prunsrv.exe //DS//TestService

So actually procrun is a fine tool that is not difficult to use. You just have to invest some time to dig into it. I hope some people will have that easier with this tutorial.

Update 2013-09-02

Due to continuing interest in the tutorial, I decided to provide a sample version on github, available here. The settings in the repository differ a little from the settings below in the paths, as my installation is a little bit different now from when I wrote this post. To use the code simply run:

git clone git@github.com:lenhard/procrun-sample.git
About these ads

93 comments

  1. Darren Lee

    Hi Jorg, would you be interested to help write a simple program with regards to microsoft services? You can reply to my email. Thanks.

  2. Hi Darren,

    I will answer here as well: I am sorry, but I have to decline. If you are looking for help with a complex procrun configuration for your software, I think the procrun mailing lists at http://commons.apache.org/daemon/mail-lists.html are the place to go.

    Kind regards, Jörg

  3. Hi ,
    The code is working fine
    I had installed the service and is showing in Services manager as “XYZService” in automatic state

    but when i am starting it from service manager, it says access denied
    when running through command line , its working fine , how to put its control into serviceManager ?

  4. Hi,
    an error message like “access denied” smells like problems with file permissions. Perhaps you are pointing the service to files (log files, etc.) that the user executing the service has no permissions to write. See: http://stackoverflow.com/q/4267051/1127892 or http://support.microsoft.com/kb/256299 that deal with this problem. A possible solution would be to fix the file permissions, or to point the service to different files. Given the service writes to the log files, what are the error messages in there?

  5. Anonymous

    Can you setup to run Jar file or a bat file as service using procrun?

    my bat files calls the jar file.
    call C:\WebSphere\AppServerV70\java\bin\java -jar %XXX_DIR_ROOT%\myProg.jar ^
    -conf %XXX_DIR_ROOT%\config\myconfig.xml ^
    -schema %XXX_DIR_ROOT%\Schema\myconfig.xsd ^

    Do we have to steup start and stop methods in the java code?

    • Well, procrun is a service wrapper for Java applications, so you can run jar files as demonstrated in the blog post. I am not aware of a way to run batch files from procrun, but that might be possible.

      You can modify your call to work with procrun if you set everything after the .jar as PR_STARTPARAMS in the installation script.

      As for the Java methods: you have to at least provide a start method (which does not have to be called this way), otherwise procrun cannot start up the service. If you don’t provide a stop method, procrun is not able to shut down the program in an ordered fashion. Instead, it will simply be killed when the system shuts down. If you have nothing to clean up or complete at any time and your program is designed to run forever, you don’t need a shutdown mechanism.

  6. Anonymous

    Thanks a lot for the reply. I will use the Jar as you have mentioned above.
    Can I use main in my java code as the start method?.
    eg:
    set PR_STARTMETHOD=main

  7. Anonymous

    Thank you for the information. it’s quite helpful.

  8. Anonymous

    Hi
    I try to run the bat file I have created as per below code.
    I get error:

    The system cannot find the path specified.
    Unable to create logger at ”

    Any ideas how to resolve it?
    Thanks heaps for any help
    Regards,

    Sara

    Code I’m using for .bat:
    —————

    set SERVICE_NAME=testService

    set PR_INSTALL=C:\myApp\ABCJava\service\prunsrv.exe

    set PR_DESCRIPTION=My Test job for Service.

    REM Service log configuration

    set PR_LOGPREFIX=%SERVICE_NAME%

    set PR_LOGPATH=c:\logs

    set PR_STDOUTPUT=c:\logs\stdout.txt

    set PR_STDERROR=c:\logs\stderr.txt

    set PR_LOGLEVEL=Debug

    REM Path to java installation

    set PR_JVM=C:\WebSphere\AppServerV70\java\jre\bin\j9vm\jvm.dll

    set PR_CLASSPATH=%XXXX_DIR_ROOT%\%XXXX_SHARED_DIR%\ABCJava\testjob.jar

    REM Startup configuration

    set PR_STARTUP=auto

    set PR_STARTMODE=jvm

    set PR_STARTCLASS=com.ABC.Printing.testjob.testjob

    set PR_STARTPARAMS=” -conf %XXXX_DIR_ROOT%\%XXXX_SHARED_DIR%\ABCJava\config\testjob.xml ^
    -schema %XXXX_DIR_ROOT%\%XXXX_SHARED_DIR%\ABCJava\Schema\testjob.xsd ^ start ^”

    REM Shutdown configuration

    set PR_STOPMODE=jvm

    set PR_STOPCLASS=com.ABC.Printing.testjob.testjob

    set PR_STOPPARAMS=” -conf %XXXX_DIR_ROOT%\%XXXX_SHARED_DIR%\ABCJava\config\testjob.xml ^
    -schema %XXXX_DIR_ROOT%\%XXXX_SHARED_DIR%\ABCJava\Schema\testjob.xsd ^ stop ^”

    REM JVM configuration

    set PR_JVMMS=256

    set PR_JVMMX=1024

    set PR_JVMSS=4000

    REM Install service

    prunsrv.exe //IS//%SERVICE_NAME%

    • Hi Sara,

      well, the error message suggests it’s a file path issue. That is really the most common issue and unfortunately it is quite hard to debug. The general guideline here is: always use absolute paths (I am not so sure about %XXX_SHARED_DIR% in your config).

      Interestingly, the error seems to relate to standard output. Does the install script have the proper admin rights to write to these log files? How about replacing the lowercase c: with an uppercase C: (not that it should matter, but who know’s). Apart from that I cannot see the error in your logging configuration. I have the same and it is working fine. Maybe it does originate from one of the other path configurations? Double check each path and try swapping it with something different. Does changing these paths have an impact? It shouldn’t if the error is really the log, because procrun creates the log before the actual service starts.

      Regards, Jörg

  9. Anonymous

    Hi Jorg,
    Thanks for your help.I changed it to use the Java mode and it worked.
    I forgot to add some libraries i was using in the setup as well.
    After that it worked.
    Trying to do this in JVM mode now.
    Thanks !!

    Sara

  10. Pingback: i want run app as windows service.

  11. Pingback: Create Windows Service Application with JAVA (procrun) « marifnst's Blog

  12. Hi Jörg,

    Works fantastic. Took me not more then 10 minutes to get everything up and running. In my case I had to modify a few aspects, though. Maybe it’s helpful for others:

    My jar file is an executable jar exported from eclipse with external jars buried within. In this case I had to define the PR_STARTCLASS as “org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader”. This one obviously picks the jars inside the executable jar up and forwards any command line arguments to the real start class defined in the manifest, eclipse has generated.

    If your startup method is “main” you can omit setting the variable since this is the default.

    And in case you do it wrong the first time the correct command to remove the service is:
    prunsrv.exe //DS//%SERVICE_NAME%

    Regards
    Dirk

    • Hi Dirk,

      I’m glad to hear the setup was fast despite the more complex setting. Also thanks for describing how to achieve it, this might actually help others! As for the command to remove the service, this is identical to the one in the post. The “>” is there to simulate a command prompt ;-) Probably, I should remove it.

      Regards
      Jörg

  13. Anonymous

    Very helpful. Thank you! – I got it working in few minutes

  14. Bar

    Jörg, this looks like just what I’m searching for, thanks!
    I’m having a problem though… the service is installed but isn’t starting correctly. The log has the following:

    [2013-03-16 12:35:09] [info] [ 1928] Starting service…
    [2013-03-16 12:35:09] [error] [ 1928] Failed creating java “C:\Program Files\Java\jre7\bin\client\jvm.dll”
    [2013-03-16 12:35:09] [error] [ 1928] The filename, directory name, or volume label syntax is incorrect.
    [2013-03-16 12:35:09] [error] [ 1928] ServiceStart returned 1
    [2013-03-16 12:35:09] [error] [ 1928] The filename, directory name, or volume label syntax is incorrect.
    [2013-03-16 12:35:09] [info] [ 3284] Run service finished.
    [2013-03-16 12:35:09] [info] [ 3284] Commons Daemon procrun finished

    I’m not sure if there’s a problem with the jvm (it really does exist at the path specified) or if somehow it’s not finding the application jar. What’s missing?
    Wondering how PR_INSTALL (an absolute path in your example) differs from the last line of your script (just the .exe filename). Notice that I’m running the cd command in my script (line1) to the directory that contains both prunsrv.exe and my application jar.

    Thanks,
    Bar

    My createService.bat is as follows (and I’m running it with the admin account):

    cd “C:\Program Files\myapp\service”
    set SERVICE_NAME=myapp
    set SERVICE_PATH=C:\Program Files\myapp\service
    set PR_INSTALL=%SERVICE_PATH%\prunsrv.exe

    REM Service log configuration
    set PR_LOGPREFIX=%SERVICE_NAME%
    set PR_LOGPATH=%SERVICE_PATH%
    set PR_STDOUTPUT=”%PR_LOGPATH%\stdout.txt”
    set PR_STDERROR=”%PR_LOGPATH%\stderr.txt”
    set PR_LOGLEVEL=Debug

    REM Path to java installation
    set PR_JVM=”%JAVA_HOME%\bin\client\jvm.dll”
    set PR_CLASSPATH=myapp-service.jar

    REM Startup configuration
    set PR_STARTUP=auto
    set PR_STARTMODE=jvm
    set PR_STARTCLASS=myapp.service.Launch
    set PR_STARTMETHOD=start

    REM Shutdown configuration
    set PR_STOPMODE=jvm
    set PR_STOPCLASS=myapp.service.Launch
    set PR_STOPMETHOD=stop

    REM Install service
    prunsrv.exe //IS//%SERVICE_NAME%

    • Hi,
      I don’t see a bug in your script, but the problem you have seems to be more common (at least for installations of tomcat). Have a look at: http://www.mkyong.com/tomcat/tomcat-error-prunsrvc-failed-creating-java-jvmdll/

      The problem with msvcr71.dll is also mentioned in the procrun faq, maybe this is your issue?

      PR_INSTALL identifies the location where prunsrv is installed. That runnable is called repeatedly by the OS (at startup), from a location we don’t know, for starting the service. This is why an absolute path makes sense there. The last line executes prunsrv a single time for installing the service (creating registry entries) from the context of the script. To sum up: the difference between the two lines is starting and installing the service.

      Hope this helps

      • Bar

        Thanks Jörg! Actually, the problem was the quotation marks! There shouldn’t be any quotations at all.
        I wasted a lot of time exploring the other issue you mentioned until I figured out the problem was much simpler…

      • Good to hear you got it solved and sorry for pointing you in the wrong direction. It’s always some fiddling with these scripts…

      • Bar

        I meant I wasted time on the msvcr dll issue even before you brought it up, so don’t feel bad :) Moral of the story: watch out for quotation marks in the script. Thanks again for this post.

  15. Elgs

    Very helpful article. Thank you so much!

  16. Enda

    Great Article – simple to follow. Thanks

  17. Good Job excelente tutorial. easy to learn how to get a service from a jar.

  18. Anonymous

    Hi Jorg, I was having a bit trouble to get the service to work. As for the application, I am using an executable jar. Following is the slightly modified script I am using:

    set SERVICE_NAME=TestService
    set PR_INSTALL=C:\Users\Saad\Desktop\Procrun\prunsrv.exe

    REM Service log configuration
    set PR_LOGPREFIX=%SERVICE_NAME%
    set PR_LOGPATH=C:\logs
    set PR_STDOUTPUT=C:\logs\stdout.txt
    set PR_STDERROR=C:\logs\stderr.txt
    set PR_LOGLEVEL=Error

    REM Path to java installation
    set PR_JVM=C:\Program Files (x86)\Java\jre6\bin\client\jvm.dll
    set PR_CLASSPATH=C:\Users\Saad\Desktop\Java Projects\SomeService.jar

    REM Startup configuration
    set PR_STARTUP=auto
    set PR_STARTMODE=jvm
    set PR_STARTCLASS=com.wordpress.joerglenhard.procrun.demo.SomeService
    set PR_STARTMETHOD=start

    REM Shutdown configuration
    set PR_STOPMODE=jvm
    set PR_STOPCLASS=com.wordpress.joerglenhard.procrun.demo.SomeService
    set PR_STOPMETHOD=stop

    REM JVM configuration
    set PR_JVMMS=256
    set PR_JVMMX=1024
    set PR_JVMSS=4000
    set PR_JVMOPTIONS=-Duser.language=DE;-Duser.region=de

    REM Install service
    prunsrv.exe //IS//%SERVICE_NAME%

    Any help would be greatly appreciated.

    • Hi,

      so what is not working, or what is the error message?

      • Saad

        Hi Jorg! Thanks for the quick response. When I run the script on the command prompt in windows 7, a second command window pops up momentarily and then disappears. So, I went to control panel-> administrative tools-> Services, and found the service listed there, but when I tried to start the service, I got an error message that read along the lines “Windows could not start the TestService on local computer”.

      • Hi Saad,
        ok that’s the typical meaningless unhelpful message you get on most occasions ;) I would bet that it is a issue with paths. In the blog post I have the installation script in the same directory as the jar and use a relative path for the classpath, whereas you use an absolute path. So your issue might be related to that. Try using a relative path and executing the script from the same directory as the jar. Also, try running the service via prunsrv in debugging mode (prunsrv.exe //DS//TestService). Maybe that gives more information on what is wrong.

  19. Jagadish

    Hi Jorg!

    How to pass one more argument other than “Start/Stop”? Please provide info
    set PR_STARTCLASS=com.demo.SomeService

    Thanks,
    Jagadish

    • Hi Jagadish,
      simply set the PR_STARTPARAMS to whatever you like in your installation script.

      • Jagadish

        Thanks a lot,
        In my services i am executing perl scripts, work flow it will connect network map drive and copy some file into local drive. This work_flow work’s fine when I start the services from command line using command “start prunsrv.exe //TS//TestService”, The same work_flow not working if I start services from Server Manager->configuration -> Services. Error message is not able connect network drive. Can you please help us solve this issue.

        Thanks,
        Jagadish

      • Hi,
        well if the service behaves differently when you start it from a relative path, then most likely there is a problem with the paths you set. It might not be elegant, but try to use absolute paths everywhere.
        Regards, Jörg

  20. Satheeshkumar

    Hi,
    My code is
    set SERVICE_NAME=LastService
    set PR_INSTALL=G:\JAVA\com\procrun\prunsrv.exe

    REM Service log configuration
    set PR_LOGPREFIX=%SERVICE_NAME%
    set PR_LOGPATH=G:\logs
    set PR_STDOUTPUT=G:\logs\stdout.txt
    set PR_STDERROR=G:\logs\stderr.txt
    set PR_LOGLEVEL=Error

    REM Path to java installation
    set PR_JVM=C:\Program Files (x86)\Java\jdk1.6.0_05\jre\bin\client\jvm.dll
    set PR_CLASSPATH=sampleprogram.jar

    REM Startup configuration
    set PR_STARTUP=auto
    set PR_STARTMODE=jvm
    set PR_STARTCLASS=SampleProgram
    set PR_STARTMETHOD=start

    REM Shutdown configuration
    set PR_STOPMODE=jvm
    set PR_STOPCLASS=SampleProgram
    set PR_STOPMETHOD=stop

    REM JVM configuration
    set PR_JVMMS=256
    set PR_JVMMX=1024
    set PR_JVMSS=4000
    set PR_JVMOPTIONS=-Duser.language=DE;-Duser.region=de

    REM Install service
    prunsrv.exe //IS//%SERVICE_NAME%

    I used commons-daemon-1.0.15-bin-windows it contains prunmgr.exe,prunsrv.exe,LICENSE,NOTICE,RELEASE-NOTES,amd64(folder), ia64(folder) , java version 1.6 , windows 8. G:\JAVA\com\procrun it contain’s createService.bat, SampleProgram.java, SampleProgram.class, sampleprogram.jar, prunmgr.exe and prunsrv.exe. When i create Service name is ZService it created no problem but When i start the service it show error message when i saw in system log it said incorrect function. My SampleProgram.java

    class SampleProgram
    {
    public static void main(String g[]){
    System.out.println(“Creating system service”);
    }
    }

    Service created,it show in the registry but i not working. It’s not show any console when i run the command it show a exe window but few of second’s it disappear. What i do guide thanks.

    • Hi,
      firstly, your Java program does not work, because you are trying to invoke the main method in a non-public class which afaik is not possible. Secondly, even if it worked, it would terminate immediately, because there is no real functionality in the main method, but just a write to the console which is done pretty quick. Just to get that clear: If your main method terminates, so does your service.
      Regards, Jörg

      • Satheeshkumar

        HI,
        Thanks for your quick respone. Suppose i create like this my program it wil work
        public class SampleProgram
        {
        public static void main(String g[]){
        while(true){
        System.out.println(“Creating system service”);
        }

        }
        }

      • Hi,
        yes, this should print the string to the console indefinitely. It will likely also drive CPU usage to its maximum and to terminate it you will have to kill the process, but that’s another story ;-)

      • Satheeshkumar

        Hi,
        I have problem for when using like this
        public class SampleProgram
        {
        public static void main(String g[]){
        while(true){
        System.out.println(“Creating system service”);
        }

        }
        }
        Service created,it show in the registry but i not working. It’s not show any console when i run the command it show a cmd window. after few of second’s it disappear. My aim is to write the time every 3 second for particular number of days. so i create the program as service, but i did not create any service please guide me.

    • Satheeshkumar

      Hi,
      Again me when i use SomeService.java it shows the same problem the service is created, and registry has entry, but not started. Same problem the console window disappear with in seconds. I am not understand what is problem can u help and guide me.

  21. Satheeshkumar

    Hi,
    My error in System Error in Windows 8 :
    The ZTimeService service terminated with the following service-specific error:
    Incorrect function.
    I did not get any error from G:\JAVA\logsstderr.txt

    Mybatch file:
    timeService.bat
    set SERVICE_NAME=ZTimeService
    set PR_INSTALL=G:\JAVA\com\procrun\prunsrv.exe

    REM Service log configuration
    set PR_LOGPREFIX=%SERVICE_NAME%
    set PR_LOGPATH=G:\JAVA\logs
    set PR_STDOUTPUT=G:\JAVA\logsstdout.txt
    set PR_STDERROR=G:\JAVA\logsstderr.txt
    set PR_LOGLEVEL=Error

    REM Path to java installation
    set PR_JVM=C:\Program Files (x86)\Java\jdk1.6.0_05\jre\bin\client\jvm.dll
    set PR_CLASSPATH=timeschedule.jar

    REM Startup configuration
    set PR_STARTUP=auto
    set PR_STARTMODE=jvm
    set PR_STARTCLASS=TimeSchedule
    set PR_STARTMETHOD=start

    REM Shutdown configuration
    set PR_STOPMODE=jvm
    set PR_STOPCLASS=TimeSchedule
    set PR_STOPMETHOD=stop

    REM JVM configuration
    set PR_JVMMS=64m
    set PR_JVMMX=128m
    set PR_JVMSS=128m
    set PR_JVMOPTIONS=-Duser.language=DE;-Duser.region=de

    REM Install service
    prunsrv.exe //IS//%SERVICE_NAME%

    My java program

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;

    public class TimeSchedule
    {

    public static void main(String g[]) throws IOException{

    FileOutputStream fos = null;
    try{

    SimpleDateFormat df = new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss”);

    File f1 = new File(“C:\\Logs\\Event\\System\\Security”);
    if(!f1.exists()){
    if(f1.mkdirs()){
    System.out.println(“Multiple directories are created!”);
    } else {
    System.out.println(“Failed to create multiple directories!”);
    }
    }
    File f = new File(“C:\\Logs\\Event\\System\\Security\\time.txt”);
    if(f.exists()){
    System.out.println(“f.exists() is exist “+f.exists());
    fos = new FileOutputStream(new File(“C:\\Logs\\Event\\System\\Security\\time.txt”),true);
    }else{
    System.out.println(“file is not exist”);
    fos = new FileOutputStream(new File(“C:\\Logs\\Event\\System\\Security\\time.txt”));
    }

    while(true){

    Thread.sleep(3000);
    Calendar cal = Calendar.getInstance();
    String Dtimr = df.format(cal.getTime());
    fos.write((Dtimr+”;”).getBytes());
    Thread.sleep(2000);
    //System.out.println(“Current Date Time : ” + df.format(cal.getTime()));

    }

    }
    catch(Exception e){
    e.printStackTrace();
    }finally{
    fos.close();
    }
    }
    }

    please guide me to create service.

  22. Satheeshkumar

    Hi Jorg,

    It’s work fine on my Window’s Xp and Windows server 2003. I didn’t know, why it is not working on 7 and 8. If you know about the reason mean’s guide me till Thank you very much for your help for my previous post and future post. Once again thank u and good post.

  23. chan

    Hi Jörg,

    I tried to create a Hello World JFrame (run minimize at backend) using Apache Daemon. I followed your steps exactly but it could not start up.

    Appreciate you could assist me on the matter. Thanks in advance.

    The error in C:\apache\demo\logs\HelloWorld.2013-09-02 showed:-
    [2013-09-02 16:45:43] [error] [ 1392] FindClass com/demo/HelloWorld failed
    [2013-09-02 16:45:43] [error] [ 9452] Failed to start Java
    [2013-09-02 16:45:43] [error] [ 9452] ServiceStart returned 4

    MANIFEST.MF:-
    Manifest-Version: 1.0
    Created-By: 1.6.0_45 (Sun Microsystems Inc.)
    Main-Class: com.demo.HelloWorld
    Class-Path: commons-daemon-1.0.15.jar

    installService.bat:-
    set SERVICE_NAME=HelloWorld
    set PR_INSTALL=C:\apache\demo\commons-daemon-1.0.15-bin-windows\prunsrv.exe

    REM Service log configuration
    set PR_LOGPREFIX=%SERVICE_NAME%
    set PR_LOGPATH=C:\apache\demo\logs
    set PR_STDOUTPUT=C:\apache\demo\logs\stdout.txt
    set PR_STDERROR=C:\apache\demo\logs\stderr.txt
    set PR_LOGLEVEL=Error

    REM Path to java installation
    set PR_JVM=C:\Program Files (x86)\Java\jre6\bin\client\jvm.dll
    set PR_CLASSPATH=HelloWorld.jar

    REM Startup configuration
    set PR_STARTUP=auto
    set PR_STARTMODE=jvm
    set PR_STARTCLASS=com.demo.HelloWorld
    set PR_STARTMETHOD=start

    REM Shutdown configuration
    set PR_STOPMODE=jvm
    set PR_STOPCLASS=com.demo.HelloWorld
    set PR_STOPMETHOD=stop

    REM JVM configuration
    set PR_JVMMS=256
    set PR_JVMMX=1024
    set PR_JVMSS=4000
    set PR_JVMOPTIONS=-Duser.language=US;-Duser.region=en

    REM Install service
    C:\apache\demo\commons-daemon-1.0.15-bin-windows\prunsrv.exe //IS//%SERVICE_NAME%

    HelloWorld.java:
    public class HelloWorld implements Daemon {
    private static HelloWorld helloWorldInstance = new HelloWorld();
    private JFrame jFrame;

    public HelloWorld() {
    initComponents();
    }

    private void initComponents() {
    jFrame = new JFrame(“Hello World App”);
    jFrame.setSize(200,300);
    jFrame.setResizable(false);
    …..
    }

    public static void main(String[] args) {
    String cmd = “start”;
    try {
    if (args.length > 0) {
    cmd = args[0];
    }
    if (“start”.equals(cmd)) {
    helloWorldInstance.start();
    }
    else {
    helloWorldInstance.stop();
    }
    }
    catch(Exception e) {
    e.printStackTrace();
    }
    }

    @Override
    public void destroy() {
    if(helloWorldInstance != null) {
    helloWorldInstance = null;
    }
    }

    @Override
    public void init(DaemonContext daemonContext) throws DaemonInitException, Exception {
    }

    @Override
    public void start() throws Exception {
    initialize();
    }

    @Override
    public void stop() throws Exception {
    terminate();
    }

    private void initialize() {
    if(helloWorldInstance == null) {
    helloWorldInstance = new HelloWorld();
    }
    }

    private void terminate() {
    // TODO Auto-generated method stub
    System.exit(0);
    }
    }

    • Hi Chan,

      from the error message, it seems that procrun is able to locate the jar file, but not the class inside it. Are you sure, that the jar file is properly constructed? Looking at your MANIFEST.mf, why is the classpath “commons-daemon-1.0.15.jar”? In the sample I just had the local dir, aka “.”. You could try changing this.

      As a side note: I just open source a working sample of the setup in the post on github: https://github.com/lenhard/procrun-sample

      • chan

        Hi Jörg,

        Ok, I removed the HelloWorld class that implements the Daemon interface.
        Then no need to put the apache-daemon-1.0.15.jar in the MANIFEST.MF.
        I changed the HelloWorld.java as follow:

        package com.demo;

        import java.awt.Image;
        import java.awt.MenuItem;
        import java.awt.PopupMenu;
        import java.awt.SystemTray;
        import java.awt.Toolkit;
        import java.awt.TrayIcon;
        import java.awt.event.ActionEvent;
        import java.awt.event.ActionListener;
        import java.awt.event.WindowEvent;
        import java.awt.event.WindowListener;
        import java.net.URL;

        import javax.swing.JFrame;

        public class HelloWorld {
        private static HelloWorld helloWorldInstance = new HelloWorld();

        private JFrame jFrame;
        private SystemTray systemTray;
        private Image bulbImage;
        private PopupMenu popupMenu;
        private MenuItem menuItemShow;
        private MenuItem menuItemHide;
        private TrayIcon trayIcon;

        public HelloWorld() {
        initComponents();
        }

        private void initComponents() {
        jFrame = new JFrame(“Hello World App”);
        jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        jFrame.addWindowListener(new WindowListener() {
        @Override
        public void windowClosing(WindowEvent e) {
        jFrame.setVisible(false);
        menuItemShow.setEnabled(true);
        menuItemHide.setEnabled(false);
        }

        @Override
        public void windowActivated(WindowEvent arg0) {}

        @Override
        public void windowDeactivated(WindowEvent arg0) {}

        @Override
        public void windowDeiconified(WindowEvent arg0) {}

        @Override
        public void windowIconified(WindowEvent arg0) {}

        @Override
        public void windowOpened(WindowEvent arg0) {}

        @Override
        public void windowClosed(WindowEvent e) {}
        });
        jFrame.setSize(200,300);
        jFrame.setResizable(false);
        if (SystemTray.isSupported()) {
        systemTray = SystemTray.getSystemTray();
        try {
        bulbImage = Toolkit.getDefaultToolkit().getImage(new URL(“http://docs.oracle.com/javase/tutorial/uiswing/examples/misc/TrayIconDemoProject/src/misc/images/bulb.gif”));
        }
        catch(Exception e) {
        e.printStackTrace();
        }
        popupMenu = new PopupMenu();
        menuItemShow = new MenuItem(“Show Me!”);
        menuItemHide = new MenuItem(“Hide Me!”);
        popupMenu.add(menuItemShow);
        popupMenu.add(menuItemHide);
        menuItemShow.setEnabled(true);
        menuItemHide.setEnabled(false);
        menuItemShow.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        jFrame.setVisible(true);
        menuItemShow.setEnabled(false);
        menuItemHide.setEnabled(true);
        }
        });
        menuItemHide.addActionListener(new ActionListener()
        {
        @Override
        public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        jFrame.setVisible(false);
        menuItemShow.setEnabled(true);
        menuItemHide.setEnabled(false);
        }
        });
        trayIcon = new TrayIcon(bulbImage, “Hello World App”, popupMenu);
        try {
        systemTray.add(trayIcon);
        }
        catch(Exception e)
        {
        e.printStackTrace();
        }
        }
        }

        public static void main(String[] args) {
        String cmd = “start”;
        try {
        if (args.length > 0) {
        cmd = args[0];
        }
        if (“start”.equals(cmd)) {
        start();
        } else {
        stop();
        }
        }
        catch(Exception e) {
        e.printStackTrace();
        }
        }

        public static void start() {
        // TODO Auto-generated method stub
        if(helloWorldInstance == null) {
        helloWorldInstance = new HelloWorld();
        }
        }

        public static void stop() {
        // TODO Auto-generated method stub
        System.exit(0);
        }
        }

        The changed MANIFEST.MF:-
        Manifest-Version: 1.0
        Created-By: 1.6.0_45 (Sun Microsystems Inc.)
        Main-Class: com.demo.HelloWorld
        Class-Path: .

        The stderr.txt:-
        2013-09-02 22:45:36 Commons Daemon procrun stderr initialized
        java.lang.NoClassDefFoundError: com/demo/HelloWorld
        Caused by: java.lang.ClassNotFoundException: com.demo.HelloWorld
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        Exception in thread “main”

        The HelloWorld.2013-09-02.log:-
        [2013-09-02 22:43:18] [error] [ 9452] FindClass com/wct/demo/HelloWorld failed
        [2013-09-02 22:43:19] [error] [ 1380] Failed to start Java
        [2013-09-02 22:43:19] [error] [ 1380] ServiceStart returned 4

        I also tried your code from https://github.com/lenhard/procrun-sample yet the error.

        I am using Windows 7 64-bit. Does this matter?

        Do you have any clue?

        Thanks.

      • I replicated your code in the sample and now procrun doesn’t find the start method. The problem seems to be that your start method has no arguments. You need to put a String array as arguments:
        public static void start(String[] args){....}
        The same applies to the stop method. If I do this, the service starts without complaining. It doesn’t start up a frame, but that’s another story I guess ;-)

      • chan

        Yes, you are right.
        I just got it done. Thanks alot.

  24. chan

    Hi Jorg,

    May I know is it possible to run a Java Swing App as Windows Service or Daemon Linux?

    I modified your code by creating a visible JFrame in your SomeService.java. Then I ran “prunsrv.exe //RS/TestService”, the service is started but no visible JFrame.
    Running it using main method in eclipse or command prompt, it is working good.

    Did I miss out anything here? Thanks.

    package com.wordpress.joerglenhard.procrun.demo;

    import javax.swing.JFrame;

    public class SomeService {

    private static boolean stop = false;

    public static void start(String[] args) {
    System.out.println(“start”);
    createGUI(); // Add JFrame here
    while (!stop) {
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(“running”);
    }
    }

    public static void stop(String[] args) {
    System.out.println(“stop”);
    stop = true;
    }

    public static void main(String[] args) {
    if (“start”.equals(args[0])) {
    start(args);
    }
    else if (“stop”.equals(args[0])) {
    stop(args);
    }
    }
    // creating the JFrame
    private static void createGUI()
    {
    JFrame frame = new JFrame(“Hello World”);
    frame.setTitle(“Hello World”);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200,300);
    frame.setResizable(false);
    frame.setVisible(true);
    }
    }

    • Hi Chan,

      yes, you can run a Swing App as a Windows Service. Your code actually works. If you execute prunsrv.exe //TS//TestService, the frame shows up. I am not so sure about //RS, but the procrun docu says its “only called from service manager”. So maybe you shouldn’t call that directly? If I was in your position, I would just install the service and start rebooting and hopefully the frame is there.

      • chan

        Hi Jörg,
        The JFrame does not show up after restart the Windows (7 64bit and XP SP3) machine.
        It only can show up when using the command prunsrv.exe //TS/SomeService
        I am using jdk1.6.0_45.

        I found this link describing about Java running as Windows Service issue:-
        http://stackoverflow.com/questions/11553598/java-as-windows-service-with-interactive-desktop-support-and-read-curren-logged

        Does this matter?

        Thanks.

      • Hi Chan,
        well it is possible to use a Swing app as a Windows Service. The application I wrapped as a service and which made me write this blog post used Swing and I never had issues with the GUI. I don’t have access to the code anymore, so I can’t give you the exact details of the setting. It was a small multithreaded app with a server core and a management interface built in Swing TrayIcon.

      • chan

        Hi Jörg,
        So, basically it is a server client application – server is running as thread silently under Windows service.
        And the Swing client communicates with the server for some reasons.
        There are 2 java processes run.

  25. SMSatheeshkumar

    Hi Jorg,
    May i know, it is possible to detect the process is running in windows service suppose some one stop the services mean’s how can i identified can you guide me. Thank you

  26. Pingback: Trouble Shooting Apache Procrun Unable to Start Service Problem- From http://lifelongprogrammer.blogspot.com/ | lifelongprogrammer

  27. Malu Ajay

    Hi,
    Myself was struggling to create a Windows service from Java application., until I found your article. Read it and tried to run the sample code. But it throws the following exception in Error Log, Any idea why?

    [2013-12-31 14:50:18] [error] [ 6044] FindClass com/nest/sample/procrun/SomeService failed
    [2013-12-31 14:50:18] [error] [ 5984] Failed to start Java
    [2013-12-31 14:50:18] [error] [ 5984] ServiceStart returned 4
    [2013-12-31 14:50:18] [error] [ 5984] Commons Daemon procrun failed with exit value: 3 (Failed to run service as console application)

    • Hi,
      since Java cannot find the specified class, this seems to be an issue with paths. You adjusted the package names from the sample (com/nest/sample/procrun), so make sure your configuration and actual path are really identical.
      Hope this helps,
      Jörg

  28. abhijeet

    hi Jorg

    Windows is not allowing me to STOP the service.. I tried putting ‘set PR_STOPPARAM=abc’ but it didnt help either.
    Below is my stop method in java.. could you please suggest what am I missing here ?

    public static void stop(String[] args) {
    try {
    System.out.println(“Stopping Poller Service…”);
    } catch (Exception ex) {
    PrintLog.writeFileLog(“In Directory watcher Exception is ” + ex.getMessage());
    }
    }

  29. abhijeet

    Log says :
    Method ‘static void stop(String[])’ not found in Class com/orion/DirectoryWatcherExample

    Whereas the STOP method is in the same class..

    • Hi,
      the method signature seems correct. Are you really sure you try to execute the jar with the most recent version of the class? Could it be that you accidently installed a previous version that did not have the stop method? I would try to uninstall the service, rebuild the jar, install the rebuilt jar, and try to run again.
      Hope this helps,
      Jörg

  30. Anonymous

    Hi,
    I am trying to install the service using a java process builder instead of using a bat file. I have not been successful though.
    Do you have an example for it?

    Thanks in Advance.

  31. K.P.Thottam

    “service terminated with service-specific error Incorrect function” – “yet another potential solution”

    Folks, I had the above error and wasn’t able to solve it with the ways that were suggested in all the earlier posts. However I did solve it by another way and I thought I should share this ‘yet another potential solution’ (YAPS) ;) with the community.

    I built my batch file as per all the instructions indicated in both the blog and comments. My java file was also done as per the sample, but I was still getting the incorrect function error.

    my YAPS:

    at command prompt fire prunmgr//ES//kptservice i.e. prunmgr//ES//yourservicename_as_in_windows

    this should bring up the GUI to edit the properties of the service. In my case I found all the values that I set via the batch script missing. So I entered them via the GUI. Next I applied the values , then restarted the service once via the GUI, everything worked as advertized and now I am a happy camper.

    Not sure why the values in the batch file did not get registered with the service, but this work around is a quick fix. I have replaced the ‘long filepath’ with ‘blah’, and I suspect the long filepath might be the cause, but for the sake of security I am not sharing the complete path.
    —————————————————————————————————————-
    set SERVICE_NAME=kptservice
    set PR_INSTALL=C:\blah\bin\prunsrv.exe

    echo is this correct?
    echo %PR_INSTALL%
    pause

    set PR_LOGPREFIX=%SERVICE_NAME%
    set PR_LOGPATH=C:\blah\logs
    set PR_STDOUTPUT=C:\blah\logs\stdout.txt
    set PR_STDERROR=C:\blah\logs\stderr.txt
    set PR_LOGLEVEL=Error

    set PR_JVM=C:\apps\java\jdk1.6.0_27\jre\bin\client\jvm.dll
    set PR_CLASSPATH=C:\blah\cpinescan.jar

    echo are these correct?
    echo JVM location %PR_JVM%
    echo Classpath %PR_CLASSPATH%

    pause
    set PR_STARTUP=auto
    set PR_STARTMODE=jvm
    set PR_STARTCLASS=ca.on.gov.erdms.escan.Test
    set PR_STARTMETHOD=start

    set PR_STOPMODE=jvm
    set PR_STOPCLASS=ca.on.gov.erdms.escan.Test
    set PR_STOPMETHOD=stop

    set PR_JVMMS=256
    set PR_JVMMX=1024
    set PR_JVMSS=4000
    set PR_JVMOPTIONS=-Dca.on.gov.erdms.jobconf=C:\blah\etc\escanjoblauncher.xml;-Djava.util.logging.config.file=C:\blah\etc\escanjoblauncher.xml

    echo is this correct?
    echo %PR_JVMOPTIONS%
    pause

    C:\blah\bin\prunsrv.exe //IS//%SERVICE_NAME%

  32. San

    Hi Jorg,
    I am trying to run my application as windows service. I got your blog. I have installed 64 bit java 7, but the folder C:\Program Files\Java\jre7\bin does not have client folder. It has server folder and it has jvm.dll. When I put this path, I am getting this error. “Failed creating java C:\Program Files\Java\jre7\bin\server\jvm.dll”. I have gone through some posts that java 6 jre has client colder under bin. The problem is my application is using java 7 features so I cant back port to java 6. How to fix this issue.

    • Hi San,
      sorry for the delay in reply. If you install a 32 bit java 7, the client folder is there and you can use Java 7 features as usual. I don’t know why they don’t package the client folder with 64 bit Java, but it should work fine with 32 bit.

  33. Anonymous

    Hi Jorg,
    Is it possible to send arguments directly to the java program that you made the windows service from? I have tried a bunch of things mainly working with PR_StartParams.

    Thanks!

    • Hi,
      yes, this works with PR_StartParams. There is probably a convention on what you can send, but this is not clear from the procrun documentation. I bet they are passed as a String array, so something of the following form should work:
      set PR_STARTPARAMS=first;second;third

      • Anonymous

        Hi Jorg,
        Thanks for the quick reply. Managed to get my service started with the correct arguments. Do you know if it’s possible to send more args to the service? Can’t seem to find anything on it.

      • Hi,
        sorry for the delay in the follow-up. You mean if its possible to send more data to the service between start and stop? I don’t think that is possible with procrun. You will have to use another mechanism for inter-process communication, such as via socket or perhaps the file system.

  34. Jim Maud

    Hi Jorg,
    A great post! I am trying to use this method to run a JBoss Fuse Karaf container application as a windows service.
    I have some problems:
    1. The service does not appear in the windows services GUI, however it can be manipulated using SC commands e.g. “sc delete JBossFuse”
    2. The service wont start
    3. I get different errors from starting the service by prunmgr and sprunsrv //RS

    Here is the bat file I created:
    rem Setup Karaf
    set KARAF_HOME=%FUSE_HOME%
    set KARAF_BASE=%KARAF_HOME%
    set KARAF_DATA=%KARAF_BASE%\data

    rem Setup the classpath
    set CLASSPATH=%CLASSPATH%;%KARAF_BASE%\conf
    pushd “%KARAF_HOME%\lib”
    for %%G in (karaf*.jar) do call:APPEND_TO_CLASSPATH %%G
    popd
    goto CLASSPATH_END
    : APPEND_TO_CLASSPATH
    set filename=%~1
    set suffix=%filename:~-4%
    if %suffix% equ .jar set CLASSPATH=%CLASSPATH%;%KARAF_HOME%\lib\%filename%
    goto :EOF
    :CLASSPATH_END

    rem Setup Java Options
    set JAVA_MIN_MEM=128M
    set JAVA_MAX_MEM=512M
    set JAVA_PERM_MEM=16M
    set JAVA_MAX_PERM_MEM=128M
    set JAVA_OPTS=-Xms%JAVA_MIN_MEM%;^
    -Xmx%JAVA_MAX_MEM%;^
    -XX:PermSize=%JAVA_PERM_MEM%;^
    -XX:MaxPermSize=%JAVA_MAX_PERM_MEM%;^
    -Dcom.sun.management.jmxremote;^
    -XX:+UnlockDiagnosticVMOptions;^
    -XX:+UnsyncloadClass;^
    -Dkaraf.startLocalConsole=false;^
    -Dkaraf.startRemoteShell=true;^
    -Djava.endorsed.dirs=”%JAVA_HOME%\jre\lib\endorsed’;’%JAVA_HOME%\lib\endorsed’;’%KARAF_HOME%\lib\endorsed”;^
    -Djava.ext.dirs=”%JAVA_HOME%\jre\lib\ext’;’%JAVA_HOME%\lib\ext’;’%KARAF_HOME%\lib\ext”;^
    -Dkaraf.instances=”%KARAF_HOME%\instances”;^
    -Dkaraf.home=”%KARAF_HOME%”;^
    -Dkaraf.base=”%KARAF_BASE%”;^
    -Dkaraf.data=”%KARAF_DATA%”;^
    -Djava.io.tmpdir=”%KARAF_DATA%\tmp”;^
    -Djava.util.logging.config.file=”%KARAF_BASE%\etc\java.util.logging.properties”

    rem service properties
    set PR_DisplayName=”JBoss Fuse Service”
    set PR_Description=”JBoss Fuse Service”
    set PR_ServiceUser=XXX\yyyyyy
    set PR_ServicePassword=xxxxxx
    set PR_Install=C:\apps\commons-daemon-1.0.15-bin-windows\prunsrv.exe

    set PR_StartMode=Java
    set PR_StartClass=org.apache.karaf.main.Main
    set PR_StopMode=Java
    set PR_StopClass=org.apache.karaf.main.Stop

    set PR_Jvm=auto
    set PR_JvmOptions=%JAVA_OPTS%
    set PR_Classpath=%CLASSPATH%

    rem install the service
    prunsrv //IS//JBossFuse

    If I start the service from the button in prunmgr //ES/JBossFuse I get these errors and indeed if I do this three times the domain account as specified in PR_ServiceUser gets locked out, though I am 100% sure the specified name and password are correct. The user is the logged in user when I create the service and it is the account we use for server administration. The same account can create and run services for other non Java programs with no issues.
    [2014-03-12 22:14:14] [info] [ 3044] Commons Daemon procrun (1.0.15.0 32-bit) started
    [2014-03-12 22:14:14] [info] [ 3044] Running ‘JBossFuse’ Service…
    [2014-03-12 22:14:14] [info] [ 3732] Starting service…
    [2014-03-12 22:14:14] [error] [ 3732] Logon failure: unknown user name or bad password.
    [2014-03-12 22:14:14] [error] [ 3732] Failed to create process
    [2014-03-12 22:14:14] [error] [ 3732] Logon failure: unknown user name or bad password.
    [2014-03-12 22:14:14] [error] [ 3732] ServiceStart returned 1
    [2014-03-12 22:14:14] [error] [ 3732] Logon failure: unknown user name or bad password.
    [2014-03-12 22:14:14] [info] [ 3044] Run service finished.
    [2014-03-12 22:14:14] [info] [ 3044] Commons Daemon procrun finished

    But when I start it from prunsrv //RS//JBossFuse I get these errors:
    [2014-03-12 22:16:05] [info] [ 9684] Commons Daemon procrun (1.0.15.0 32-bit) started
    [2014-03-12 22:16:05] [info] [ 9684] Running ‘JBossFuse’ Service…
    [2014-03-12 22:16:05] [error] [ 9684] StartServiceCtrlDispatcher for ‘JBossFuse’ failed
    [2014-03-12 22:16:05] [error] [ 9684] The service process could not connect to the service controller.
    [2014-03-12 22:16:05] [error] [ 9684] Commons Daemon procrun failed with exit value: 4 (Failed to run service)
    [2014-03-12 22:16:05] [error] [ 9684] The service process could not connect to the service controller.

    I hope you could help me.
    Thank you
    Jim

    • Hi Jim,
      that’s a somewhat more advanced setup you have there. I have never used ServiceUser properties, etc., so I’m afraid that I can’t really help you. However, both of the error messages “smell” like authentication problems. To help with debugging: Does the service install correclty when you skip user and password and just install it with administrator privileges?
      Regards, Jörg

  35. Fred

    Hi Jorg,

    I have a program that I started as a network service. It starts and stops fine. I can send it a command from cmd to check the status and that returns fine, but when I send it a command to spawn a new thread it starts the process, then it sits there hung up until i terminate the process.

    What I’m wondering is if this is a limitation of procrun or something else?

    Anything would be helpful on this. Thanks

    • Hi Fred,

      as far as I understand, procrun only hooks the java program into the service api of the operating system. It does not interfere into the programs regular execution or influence threading. Threading is determined by the JVM which you declare in the procrun configuration.

      So all in all, I think you should look for the deadlock in your application. Does it work fine when you leave out procrun? I once wrote a network service with several threads using procrun and didn’t experience threading problems.

      Hope this helps, Jörg

      • Fred

        Yes it works fine without procrun. What is the best method for finding a deadlock?

      • If it works fine without procrun, then there is no deadlock. “Deadlock” means that your application reached a state where it can no longer make progress, aka it is “hung up”.

        If your service works without procrun but not with it, then yes, the error might very well be related to procrun. Unfortunately, I can’t really help you there, as I haven’t experienced such problems myself. You should probably ask at the procrun mailing list.

  36. Zain

    Hi I am getting error Service TestService is missing ImageFile… Can you help ?

  37. winning

    Hi,

    I downloaded your procrun-sample from git. I ran the installService.bat after edited the PR_INSTALL and PR_JVM paths. Although the cmd (created by installService.bat) fired up a new window, the new window closed very very soon. It should be showing “start running running….” in normal, right?
    After that, i went to the task mgr and found that the testService was existing but stopped.

    Could you tell me what should I do to create a normal testService? T^T

    • Hi,

      that is the normal behavior of installService.bat. It installs the service into the system, which is why you see that the service exists, but it does not start the service, and hence you see it as stopped.

      After executing installService.bat, the service can be treated as any other service, so you can just use the normal Windows tooling to start it. Alternatively, you can execute “prunsrv.exe //TS//TestService” to use the diagnosis tooling available with procrun. This fires up the service in the console and you see the “start running running, etc.”.

      Hope this helps!
      Jörg

  38. Ramzi

    Hi Jorg,
    Thanks for this article. I have some issue though trying to run the executable jar file as a windows service. When I run my “service.bat” script, the service (TestService) appears on the service manager, but when i try to run it , i have a pop up message that says : “Windows cannot run TestServuce on the local Computer. Error 2: cannot find the file specified”

    I have no idea where it come from. The jar alone works fine when i run it with a command line.

    here’s my service.bat content:

    set SERVICE_NAME=TestService
    set PR_INSTALL=prunsrv.exe

    REM Service log configuration
    set PR_LOGPREFIX=TestService
    set PR_LOGPATH=C:\Users\CU_APP_DREAM_D\Desktop\DataCapture\logs
    set PR_STDOUTPUT=C:\Users\CU_APP_DREAM_D\Desktop\DataCapture\logs\stdout.txt
    set PR_STDERROR=C:\Users\CU_APP_DREAM_D\Desktop\DataCapture\logs\stderr.txt
    set PR_LOGLEVEL=Error

    REM Path to java installation
    set PR_JVM=C:\Program Files\Java\jre7\bin\server\jvm.dll
    set PR_CLASSPATH=C:\Users\CU_APP_DREAM_D\Desktop\DataCapture\someservice.jar

    REM Startup configuration
    set PR_STARTUP=auto
    set PR_STARTMODE=jvm
    set PR_STARTCLASS=fr.real.flow.manager.SomeService
    set PR_STARTMETHOD=start

    REM Shutdown configuration
    set PR_STOPMODE=jvm
    set PR_STOPCLASS=fr.real.flow.manager.SomeService
    set PR_STOPMETHOD=stop

    REM JVM configuration
    set PR_JVMMS=256
    set PR_JVMMX=1024
    set PR_JVMSS=4000
    set PR_JVMOPTIONS=-Duser.language=DE;-Duser.region=de

    REM Install service
    prunsrv.exe //IS//TestService

    Do you have any idea ?
    Thak you for your help.

    Ramzi

    • Hi Ramzi,

      with that error, I’m almost certain that it is an issue with file paths. Have a look at the second line of your script:

      set PR_INSTALL=prunsrv.exe

      This is a relative file path and for some reason procrun won’t handle this well when used with administrative tooling. Citing from the blog post: “Next, you need to set the path to prunsrv.exe. On that note, here is a lesson that took me some time to learn: If you use (correct) relative paths to files in the installation script, the service will install correctly and it will run fine in debugging mode. It will however fail when run normally with any administrative tooling you have. …. Generally, you should use absolute paths with procrun.”

      In summary: Use an absolute path here, similar to my script in the post, then it should work.

      Regards
      Jörg

      • Ramzi

        Thanks Jörg,

        You were right and the issue was in the PATH. Now I have some other issue, the service get installed , but when i go to the service manager and try to start it I get this error:

        “Windows could not start the TestService on Local Compute. For more information, review the System Event Log if this is a non Microsoft Service contact the service vendor, and refer to service-specific error code 1.”

        I’m trying to find some solutions online (google, etc…) but nothing really useful for now. So If you have experienced this kind of errors , or if you have any idea when it can come from i’ll be glad to know :)

        I packaged my java code with maven using the “maven-shade-plugin”. The executable jar that was created works fine when i execute it with a command line. But is impossible to run as a service (getting the error i gave previously).

        This could be maybe a problem with the java version ? I doubt it but i’ve read some posts online that had the similar error but in other contexts and it was due to java

        I’m using :

        java version “1.7.0_17″
        Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
        Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)

        On a : Windows Server 2008 R2 Entreprise OS

        Thanks for your help and your time

        Regards,
        Ramzi

      • Hi Ramzi,

        hm, that is a really meaningless error. I also don’t think it’s a problem with the Java version, 1.7.X should be fine (1.8 might not). Is there any more concrete information in the log files of the service?

        The only thing I can think of at the moment: A classic problem is if you execute the installation without administrator priviliges. This might work, but fail with a meaningless error later on. Did you execute the script in a command prompt that was started with administrator privileges?

        Regards
        Jörg

  39. Ramzi

    Ok, it turned out to be a problem with The java: I uninstalled the 64bits version that I had on my local computer and installed the 32bits , and it works fine now. I have no Idea why, my OS is 64bits, but it works!

    Thanks for your help!

    Regards,
    Ramzi

    • Glad to hear you got it working! I’ve heard of similar problems before from other people. In some cases, the jvm.dll referenced in “set PR_JVM=…” seems to not to be present in the 64bit JRE. I have no idea why and when this is the case and it is present in all the 64 bit JREs I have available on my system (Java 6,7, and 8).

      Anyways, good you got it fixed!

  40. csh

    Thanks for this tutorial, it helped me a lot!

    But do you know what the org.apache.commons.daemon.Daemon interface is used for?

    It seems the service runs without it. You just need to implement a static start(String[] args) method, right?

    I wonder why there’s this interface then.

    • I’m glad to hear it helped :) I remember looking at the Daemon interface, but I have never actually used it. You can implement your service without the interface and just with the help of static startup and shutdown methods.

      I can’t find much information about the Daemon interface, but a source code comment in http://wiki.apache.org/commons/Daemon says the following: “Implementing the Daemon interface is not required for Windows but is for Linux”. So as long as you just aim at Windows, you should be fine.

      • csh

        Thank you for your quick answer!

        Another problem I have: I have installed the service appearently successfully and if I start it on the console with start prunsrv.exe //TS/Servicename it works perfectly, but if I start it from Windows’ Services View or with prnmanager.exe (which I renamed), it doesn’t fully start.

        I mean, I can even see my application logs in the logs folder, the service is marked as “started” and everything seems fine, but it doesn’t show any UI in that case. I am using a JavaFX application as service. The JavaFX window just doesn’t want to popup. Probably some JavaFX quirks…
        Ever seen this?

      • Hm, I have implemented Swing-Apps as service, but not JavaFX so far. The Swing-Apps were working fine without any issues.

        In my experience, when procrun runs fine in debugging mode but not with the Windows tooling, it comes down to pathing issues. Is there a relative path anywhere in your installation script? If yes, try replacing that with an absolute path.However, your problem sounds different, since the application is running (as indicated by the logs), but no UI shows up. This really might be something with JavaFX… What Java version are you using? Maybe procrun misses jars related to JavaFX?

      • csh

        Yes, I’ve had this pathing issue, too. But in this case the service won’t even start at all. My paths are absolute.

        If I use
        prunsrv.exe //TS//MyService it works!

        If I use
        prunsrv.exe //ES//MyService it won’t work (seems to be the same, when starting from the Windows Services View). The service is started, application logs are fine, but no UI. I’ve even logged “Showing window” before calling the show() method on the JavaFX window. It is logged in the logs, but no windows shows up…

        Using Java 8.05. JavaFX is embedded there.

        Thanks for your help though, I will investigate further.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 36 other followers