### 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 {
} 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

## 149 thoughts on “Build windows service from java application with procrun”

1. Darren Lee says:

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 ,
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 ?

3. 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?

4. Anonymous says:

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?

1. 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.

5. Anonymous says:

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

6. Anonymous says:

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

7. Anonymous says:

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%

1. 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

8. Anonymous says:

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

9. 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

1. 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

1. You are right. Sorry I overlooked that.

Keep it in, since almost everybody needs a second shot I guess.

Regards,
Dirk

10. Anonymous says:

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

11. Bar says:

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%

1. 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

1. Bar says:

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…

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

1. Bar says:

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.

12. Elgs says:

Very helpful article. Thank you so much!

13. Enda says:

Great Article – simple to follow. Thanks

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

15. Anonymous says:

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

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

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 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”.

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.

Hi Jorg!

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

Thanks,

simply set the PR_STARTPARAMS to whatever you like in your installation script.

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,

2. 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

17. Satheeshkumar says:

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.

1. 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

1. Satheeshkumar says:

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”);
}

}
}

2. 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 ;-)

3. Satheeshkumar says:

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.

2. Satheeshkumar says:

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.

1. Well, you specify log files for a reason. What do the log files say?

18. Satheeshkumar says:

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){

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

}

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

please guide me to create service.

1. Satheeshkumar says:

Hi,

Again me When i create service on Window 7 same error is show for me The ZTimeService
service terminated with service-specific error Incorrect function. When i choose prunsrv.exe is in the wrong package ? or something else ? How can i create a ZTimeService Help and Guide me thnaks

19. Satheeshkumar says:

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.

20. chan says:

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);
}
}

1. 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

1. chan says:

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.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 TrayIcon trayIcon;

public HelloWorld() {
initComponents();
}

private void initComponents() {
jFrame = new JFrame(“Hello World App”);
jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
@Override
public void windowClosing(WindowEvent e) {
jFrame.setVisible(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();
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
jFrame.setVisible(true);
}
});
{
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
jFrame.setVisible(false);
}
});
trayIcon = new TrayIcon(bulbImage, “Hello World App”, popupMenu);
try {
}
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)
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.

2. 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 ;-)

1. chan says:

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

21. chan says:

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 {
} 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);
}
}

1. 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.

1. 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.

1. chan says:

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.

22. SMSatheeshkumar says:

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

23. Malu Ajay says:

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)

1. 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

24. abhijeet says:

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());
}
}

25. abhijeet says:

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

Whereas the STOP method is in the same class..

1. 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

26. Anonymous says:

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?

1. Hi,
sorry, but I have to disappoInt you. I don’t have an example for a process builder.
Regards, Jörg

27. K.P.Thottam says:

“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%

28. San says:

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.

1. 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.

29. Anonymous says:

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!

1. 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

1. Anonymous says:

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.

2. 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.

30. Jim Maud says:

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;^
-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_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

1. 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

2. Anonymous says:

Maybe this will help: I had the same problem even with the correct credentials.
The problem was that I was using the 32 bit version of the executable. The error message was confusing…

31. Fred says:

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

1. 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

1. Fred says:

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

2. 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.

32. Zain says:

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

1. Anonymous says:

Do you find any solution? I have this same problem.

2. AMC says:

In case someone else gets this error like I did, if you are executing this script from the command prompt, you must launch command prompt as administrator.

1. Indeed. Let me remark that this is written in the blog post :-) “The script modifies the registry, so it needs to have administrator privileges to execute successfully”

33. winning says:

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

1. 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

34. Ramzi says:

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

1. 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

1. Ramzi says:

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

2. 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

35. Ramzi says:

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

1. 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!

36. csh says:

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.

1. 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.

1. csh says:

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?

2. 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?

3. csh says:

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.

37. Anonymous says:

It worked very nicely.. Thanks for this noble help to community…..

38. Anonymous says:

HI
Showing error while starting the service,i am stucked with this

‘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’

please give me any solution for this. (Other than change to 32bit version )

39. Shebin says:

Showing error when starting the service.i m stucked with this.

‘Windows could not start the Service on Local Computer. 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’

please give me any solution for this.(Other than change to 32bit jre)

shebin

40. Anonymous says:

Hi Jorg,

Your documentation was extremely helpful. I have a question, My java code depends on multiple .jar files during runtime. Is there a way we can specify a directory as class path which will have all the jar files ?

For example: i am using log4j that writes my statements to a file. For the jvm to locate the logger I am giving the full path to the .jar in the classpath. But I have more 20 jar files my project depends on, so is there a way I can give a directory as a classpath ??

Thankyou.

1. Hi,

first of all: congratulations to the 100th comment to this post ;-)

Regarding your question: This should be no problem at all. Procrun uses the normal Java classpath syntax in its classpath configuration, so you should be able to use the wildcard character, for instance:
set PR_CLASSPATH=path-to-jars/*

Regards,
Jörg

41. Anonymous says:

Awesome, it worked. Thank you so much :)

42. Dhandapani S says:

Hi Jorg,
Thank you for the tutorial. it was really helpful setting up my windows service.
My service is up and running good.
yet i faced one problem,I need to turn on “Allow service to interact with desktop” after the service installation under the service Log On properties.
Without this setup my java component is not interacting with the desktop.
I did not get any error.
I do have administrator privilege and setup the service with that.
Is there a way i can set this field when i do the service installation.

Thank you
Dhandapani S

1. Hi Dhandapani S,

I have never tried this, but according to the procrun documentation, there is a parameter called Type which you can use. From the documentation: “Service type can be interactive to allow the service to interact with the desktop. Use this option only with Local system accounts.” You should probably try this.

Regards,
Jörg

43. hi Jorg,

i am struggling with one problem i.e I can start / stop and restart windows service by setting –StartMode =jvm and loding jre\client\jvm.dll file (means for wind -32 bit).

But if i switch for –StartMode=Java it is creating problem while stopping service.
I need to wait for long time and then it will show some error.

1. Hi kiran,

this is hard to tell without knowing the actual error message.

44. Shakthi says:

Hi Jorg,
Will this work for 32-bit windows machine?

1. Hi Shakthi,
so far I have never tried it on a 32-bit machine, but the procrun man page says it works.
Regards, Jörg

1. I have tried using 32-bit windows machine with same procedure as mentioned above, but its failed to add service. Any help is appreciated please..

45. Hi Jorg,
I have succeeded with 64-bit windows OS, but not with 32-bit windows OS, where I have followed the same procedure which I did for 64-bit windows OS.
Regards,
Shakthi

46. Hi Jorg,
Any thoughts on My previous comment, I have also tried but no success :(, Plz help me on this..

1. Hi shakthi,
sorry, during Christmas and New year i take a little longer to respond ;) besides, there is hardly anything i can say except: what error message are you getting? What is written into your error log?
Regards, Jörg

1. Hi Jorg,
Sorry for the delay, I have resolved my issues, I just need to put different procrun.exe for 32-bit windows machine.
After changing the 32-bit procrun.exe in 32-bit machine, its works like a charm.

Also I would like to thank you for the awesome tutorial. This tutorial really helped me a lot of how to create a windows service application.

Thanks again and keep up your good work. :)

Regards,
Shakthi Elango.

2. Good to hear you got everything to work and I am glad my tutorial helped!

Regards, Jörg

47. Michael Pigg says:

Jorg,
I have followed your instruction step-by-step and it to working just fine.
However, nothing is written to the log files.
How can I write something to the log file from the java class? Can I have some example?

1. Michael Pigg says:

never mind. Jorg. I found the error in my code.
My morning coffee hasn’t kicked in yet.

1. I am always happy when I can help people without actually doing anything ;-)

48. Hi Jorg,
Could we able to add ‘recovery actions’ scripts using procrun?

Thanks & Regards
Shakthi Elango.

1. Hi Shakthi,
I haven’t used recovery actions myself so far and I can’t find information on that on the procrun homepage. So I would guess no, but this is really only a guess. Maybe you will get support on this on the mailing list.
Regards, Jörg

49. Rama says:

Hi,
I am facing problem, when I am starting HornetQ , HornetQ has beeen started but status in services blank.. How Status will show stopped to Running

50. Anonymous says:

Hello Lenhard,
Thanks for your help.
I tried your project,but when I try to run it,I got an error “,FindClass failed
Also,I tried and build many others,but I got the same error about find class even I do have the jar.

1. Hi,
the project doesn’t work by itself. It depends on actual file system paths that have to be adjusted for your system. The error you get sounds as if your file paths do not fit to your system.

51. Anonymous says:

I did changed the path.
set SERVICE_NAME=TService
set PR_INSTALL=F:\folder\OSGIWIN\procrun-sample-master\prunsrv.exe

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

REM Path to java installation
set PR_JVM=C:\Program Files\Java\jdk1.8.0_20\jre\bin\server\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 service
prunsrv.exe //IS//%SERVICE_NAME%

1. So what messages are written to your logs? “FindClass failed” is really too unspecific for anything but guessing.

52. Anonymous says:

Thanks for your help.
Now , I used prunmgr.exe and renamed it to the service name.In the logging file,I get
[2015-03-03 20:19:46] [info] [17308] Commons Daemon procrun (1.0.15.0 64-bit) started
[2015-03-03 20:19:46] [info] [17308] Running ‘TService’ Service…
[2015-03-03 20:19:46] [info] [17080] Starting service…
[2015-03-03 20:19:46] [error] [17080] Missing service ImageFile
[2015-03-03 20:19:46] [error] [17080] ServiceStart returned 1
[2015-03-03 20:19:46] [info] [17308] Run service finished.
[2015-03-03 20:19:46] [info] [17308] Commons Daemon procrun finished

53. Anonymous says:

Thanks for your help.
when I used prunmgr.exe and renamed it to the service name and used mode:”jvm”.In the logging file,I get
[2015-03-03 20:21:45] [info] [ 5864] Commons Daemon procrun (1.0.15.0 64-bit) started
[2015-03-03 20:21:45] [info] [ 5864] Running ‘TService’ Service…
[2015-03-03 20:21:45] [info] [ 7180] Starting service…
[2015-03-03 20:21:46] [error] [ 7796] FindClass com/wordpress/joerglenhard/procrun/demo/SomeService failed
[2015-03-03 20:21:46] [error] [ 7180] Failed to start Java
[2015-03-03 20:21:46] [error] [ 7180] ServiceStart returned 4
[2015-03-03 20:21:46] [info] [ 5864] Run service finished.
[2015-03-03 20:21:46] [info] [ 5864] Commons Daemon procrun finished

54. So procrun can’t find the class in the jar file. Is the jar properly constructed? Is the class file in there?

55. Anonymous says:

I didn’t change the “someservice.jar”.when i open its manifest. it contains:
Manifest-Version: 1.0
Class-Path: .
Main-Class: com.wordpress.joerglenhard.procrun.demo.SomeService

1. If the error is not in your paths and not in the jar (though it still sounds as if the jar is missing the class file), the only remaining part is your java runtime or your operating system. But I can’t really say more. Maybe you can get more help on stackoverflow?

56. Anonymous says:

yes,the class file in there.

57. I am getting below error and service not starting

[2015-03-16 21:32:03] [debug] ( prunsrv.c:1679) [ 3300] Commons Daemon procrun log initialized
[2015-03-16 21:32:03] [info] ( prunsrv.c:1683) [ 3300] Commons Daemon procrun (1.0.15.0 64-bit) started
[2015-03-16 21:32:03] [info] ( prunsrv.c:1596) [ 3300] Running ‘SlaveService’ Service…
[2015-03-16 21:32:03] [debug] ( prunsrv.c:1374) [ 3676] Inside ServiceMain…
[2015-03-16 21:32:03] [debug] ( prunsrv.c:844 ) [ 3676] reportServiceStatusE: 2, 0, 3000, 0
[2015-03-16 21:32:03] [info] ( prunsrv.c:1127) [ 3676] Starting service…
[2015-03-16 21:32:03] [debug] ( javajni.c:222 ) [ 3676] Invalid RuntimeLib ‘C:\Program Files\Java\jre7\bin\client\jvm.dll’
[2015-03-16 21:32:03] [debug] ( javajni.c:224 ) [ 3676] Using Jre JavaHome ‘C:\Program Files\Java\jre7’
[2015-03-16 21:32:03] [debug] ( javajni.c:233 ) [ 3676] loading jvm ‘C:\Program Files\Java\jre7\bin\server\jvm.dll’
[2015-03-16 21:32:03] [debug] ( javajni.c:704 ) [ 3700] Jvm Option[0] -Djava.class.path=C:\automation\connectslave.jar
[2015-03-16 21:32:03] [debug] ( javajni.c:704 ) [ 3700] Jvm Option[1] exit
[2015-03-16 21:32:03] [debug] ( javajni.c:941 ) [ 3700] Java Worker thread started com/Test/ConnectTest:main
[2015-03-16 21:32:03] [debug] ( javajni.c:952 ) [ 3700] Exception has been thrown
[2015-03-16 21:32:03] [debug] ( javajni.c:964 ) [ 3700] Java Worker thread finished com/Test/ConnectTest:main with status=6
[2015-03-16 21:32:04] [debug] ( prunsrv.c:1186) [ 3676] Java started com/Test/ConnectTest
[2015-03-16 21:32:04] [info] ( prunsrv.c:1284) [ 3676] Service started in 1174 ms.
[2015-03-16 21:32:04] [debug] ( prunsrv.c:844 ) [ 3676] reportServiceStatusE: 4, 0, 0, 0
[2015-03-16 21:32:04] [debug] ( prunsrv.c:1528) [ 3676] Waiting for worker to finish…
[2015-03-16 21:32:04] [debug] ( prunsrv.c:1533) [ 3676] Worker finished.
[2015-03-16 21:32:04] [debug] ( prunsrv.c:1559) [ 3676] Waiting for all threads to exit
[2015-03-16 21:32:04] [debug] ( prunsrv.c:844 ) [ 3676] reportServiceStatusE: 3, 0, 0, 0
[2015-03-16 21:32:04] [debug] ( prunsrv.c:1563) [ 3676] JVM destroyed.
[2015-03-16 21:32:04] [debug] ( prunsrv.c:844 ) [ 3676] reportServiceStatusE: 1, 1066, 0, 1
[2015-03-16 21:32:04] [info] ( prunsrv.c:1598) [ 3300] Run service finished.
[2015-03-16 21:32:04] [info] ( prunsrv.c:1764) [ 3300] Commons Daemon procrun finished

1. Anonymous says:

I too get this exact error. Only difference is I try to start another piece of java code.

58. Thanks boss for this tuto. Very Helpful. Bye my friend

1. To add a description to this service? Now I see only the name without it…..which is the parameter? THANKS

2. Sorry for the long delay in answering. These conference always lead to overflows in my inbox…

Anyways, the parameter to set the description should simply be “–Description”.

59. Mike says:

Hey Jörg,

I know this is an old post but thanks for sharing it.
One thing to add that’s been holding me up all day is that you should never wrap your PR_CLASSPATH in quotes, even if it contains spaces as this will lead to ClassDefNotFound exceptions every time!

Cheers

1. Hi Mike,

an old post, but somehow still very popular. Anyways, thanks for sharing the info, I am sure it will help others!

Regards, Jörg

60. Terry Luo says:

hi Jörg,

your great article really helped me a lot. now I was able to install the service. also both start and stop are indeed good after checking prunsrv’s log(no error). but one thing annoying still have one error entry in Event Viewer Application log.

Faulting application name: prunsrv.exe, version: 1.0.15.0, time stamp: 0x51543b9d
Faulting module name: jvm.dll, version: 25.5.0.2, time stamp: 0x5327ff3c
Exception code: 0xc0000005
Fault offset: 0x00000000001f5688
Faulting process id: 0xdac
Faulting application start time: 0x01d0ca9ed8aea35f
Faulting application path: d:\abc\def\data\prunsrv.exe
Faulting module path: C:\Program Files\jdk1.8.0_05\jre\bin\server\jvm.dll
Report Id: 277978d1-3692-11e5-8e95-005056333ddb

env: prunsrv 1.0.15, AMD 64bit. Windows 2008R2 64-bit
attached bat here.

@echo off
set CLASSPATH=%CD%\lib\AAA.jar;%CD%\lib\BBB.jar;%CD%\lib\CCC.jar;
echo %JAVA_HOME%
set JVM_DLL=%JAVA_HOME%\jre\bin\server\jvm.dll

rem prunsrv log settings
set logPath=%CD%\log
set prefix=prunsrv
set stdError=%logPath%\%prefix%_error.log
set stdOutput=%logPath%\%prefix%_output.log

set serviceName=”MyDataService”
set description=”My Data Service”
set startClass=com.htf.guarantee.data.engine.Program
set stopClass=%startClass%
set JAVA_JMX_PORT=6060
set jvmOption=-Drs.env=dev#-Drs.dbenv=qa#-DlogFolder=%logPath%\dev

set prunsrv_exe=%CD%\prunsrv.exe

%prunsrv_exe% //IS//%serviceName% –Description=%description% –Startup=auto –Jvm=”%JVM_DLL%” –JvmMx=640
–StartMode=jvm –StartClass=%startClass% –StartMethod=main –StopMode=jvm –StopClass=%stopClass% –StopMethod=stop
++JvmOptions=%jvmOption% –LogPath=%logPath% –StdError=%stdError% –StdOutput=%stdOutput% –Classpath=%CLASSPATH%

I’m sure all absolute path here. would be great to have your help to fix that error.

Thanks…
Terry

1. Hi Terry,

Regards, Jörg

61. Hi Jörg,

help:

[warn] The system cannot find the Registry key for service ‘prunsrv’
[error] Load configuration failed
[error] Commons Daemon procrun failed with exit value: 2

1. Hi Janderson,

well, sounds like the installation process failed? Did you try to install with admin privileges?

Regards, Jörg

62. Jorg,
With your Service Log Configuration, does the log file roll when it reaches the max size or daily?
I would like to know if there is something “RollingFileAppender” like configuration.

1. Hi Michael,
as far as I know, the log file will not roll and there is no configuration option to achieve this. See also: https://issues.apache.org/jira/browse/DAEMON-213
I think it would be best to write as little as possible to stdout and stderr and use a custom logging mechanism with proper rotation instead.
Regards, Jörg

63. Andrew Lienhard says:

Thanks for this tutorial. Got it running without any issues. This will be very helpful in a project I’m starting. PS — I suspect our last names share a common origin!

1. You are welcome! It is good to read that the tutorial is still useful after four and a half years! PS – I suspect you are probably correct ;-)