Java Service Launcher is a Java Service Wrapper used to start 32bit and 64bit Java-programs as a Windows Service
Current Release: JSL 0.99x
Release Date: December 2021
Download: jsl.zip
Older Versions and change log: Change log and archived versions
SourceForge https://sourceforge.net/projects/jslwin/
Contact by Mail: michael@roeschter.com
Contact by Phone: +49 157 5616 8246 (Central European Time)
License: Public Domain
Home Page:

http://www.roeschter.de/index.html

Index

 

  1. What is JSL
  2. Getting Started
  3. Requirements
  4. Examples
  5. Release Information
  6. Support
  7. Change log and archived versions
  8. FAQ
  9. Links
  10. License
  11. Documentation
  12. Sample Configuration

What is the JSL?

Java Service Launcher is a Java Service Wrapper, a small executable used to start 32bit and 64bit JAVA-programs as a Windows Service.

Note that JSL is NOT a JVM. It's simply a utility like java, javap, javac or javah which will launch a Java application through an already an installed JVM.

64bit and 32bit should work with Windows 7 and later (last tested version is Windows 10). No recent tests have been performed on Windows XP or older.

JSL should work with any JVM fom Java 1.2 onwards as the JNI interfaces used to launch the JVM has been standardized by Sun early on. JSL Has been tested with OpenJDK based JDKs like Azul Zulu, and Oracle's JDK. JSL has also been used with IBMs J9.

Getting Started

How To start my java programm as a service

Quick start

  1. Copy JSL.EXE (or JSL64.exe) and JSL.INI somewhere to your disk.
  2. Modify the JSL.INI to reflect your desired settings. Setting the Java cmdline and jrepath should be sufficient
  3. Run jsl.exe -install
  4. Start it in the NT service manager or by calling NET start "TelnetEcho"

Setup

The jsl executable will look for an ini file with the same name as the executable in it's directory. You can copy and rename jsl.exe amd jsl.ini to your convenience, just make sure names match. E.g. myserver.exe must go along with myserver.ini.

Initialization file

The initialization file is both necessary for setup and running the service. Don't remove it after you have installed the service. It contains parameters for both service setup and java application.

See here for an examples

Command line options

Calling jsl.exe without parameters gives an overview of the available options.

-install

Install the service in the NT service manager. Service is not started immediately, though it will start automatically when NT is rebooted.
Start the service from command line with NET START <APPNAME>.

-configure

Will reconfigure from the current configuration file

-remove

Remove an installed service. This may fail if the service is still running.
Stop the service from command line with NET STOP <APPNAME>.

-debug

Run the application from command line for debugging purposes. A service need no be installed.

You can simulate and test service stop, pause and continue behavior on the command line by starting with -debug option. Use CTRL-C for stop service, CTRL-BREAK will toggle between pause and continue service.

-run

Run the application from command line for test. Should behave like running the program with java.exe

-runapp

Run the application from command without console. Useful for starting graphical applications. Note that you will not see ANY output unless you redirected stdout/stderr or run in debug mode, which logs to a file.

-console hide|attach|new

Optional parameter to produce javaw like behavior. "-console hide" will not open a console and not show any output. "-console attach" (default) will attach to the current console, usually the command prompt. "-console new" will open a new console and show all output there.

Full command line options

jsl.exe -install|configure|remove|run|runapp (<ini file>) (-console hide|attach|new)

Stopping a service

JSL can call a static method to signal the shutdown request. This is configured in the configuration file:

stopclass=java/lang/System

stopmethod=exit
stopsignature=(I)V

As you see above the simplest (and the default) is to call System.exit(0). If you want to do some shutdown install a shutdown hook in the JVM or simple call some other static method of your own design. Just don't forget to actually call System.exit() in the end else JSL and the Service Manager will be confused and might not report the sevice as stopped.

Logging and debugging

Quite possibly your Java application will run flawlessly as a service immediately. If not please read ahead.

JSL will not produce any log output by default (other than what logging your Java application does anyway). It is therefore highly recommended to run the application from command line first through "jsl -run" and "jsl -debug" options. Debug mode will produce a log file in the work directory.

When requiring logging while running as a service you may use the jsl_debug executable, which produces a log file. Or you may redirect output to files. This can be configured for C stdout/stderr (mostly JSL startup logs) and Java System.out and System.err. Please see the .ini file for details.

Requirements

Which software is needed to run a Java program with JSL?

JSL needs no setup. Jsl.exe and jsl.ini can simply be copied anywhere. Please note the limitations concerning running in a network as explained in the FAQ.

JSL will work with Windows 10, Windows 7 and contemporary Windows servers. Recent versions have not been tested on Windows XP, BUT as my code base is conservative they may still work.

JSL works fine with both JDK or JRE. 32bit and 64bit OS versions as well as 32bit and 64bit JVMs JRE/JDK versions since Java 1.2

You need a 64bit OS to run 64bit JSL, but you can also run the 32bit version on a 64bit OS. The 64bit JSL starts the 64bit JVM and the 32bit JSl run the 32bit JVM.

JSL needs Java installed of course. If Java is properly installed the JSL will find it automatically through the registry entry. If not, or if you do not like this behaviour, just set the jrepath option in the configuration file. All common JRE and JDK will be found in the registry. Oracle, Azul, AdoptOpenJDK for all Java version till Javav 17. If you want more fine grained control over which version is started pelase check the option in the JAVA section of the ini file.

Examples

For an example of a simple java service please see jsl.ini or jsl64.ini in the bin directory.

To run it adjust the classpath in the jsl.ini (at the very end) and run jsl.exe (no parameters) from command line.

The output shoud look like this

JSL Java Service Launcher by Michael Roeschter
(Michael@Roeschter.com)
Version 0.99r May 2019
Command line options:
jsl64 -install [ini] [...]    to install the service
jsl64 -configure [ini] [...]  to reconfigure an installed service with new dependencies
jsl64 -remove [ini] [...]     to remove the service
jsl64 -debug [ini] [...]      to run as a console app for debugging
jsl64 -run [ini] [...]        to run as a standalone console app
jsl64 -runapp [ini] [...]     to run as a standalone app with no console output
jsl64 -ini ini                to use the specified init file for running as a service (this option is not useful on command line; only use it if you configure the service option in the registry)
Optional parameters: [...] -console hide | attach | new    'hide' will not show any output on console; 'attach' will show output in current console; 'new' will open a new console window
The configurations file used in the -install and -configure commands will be used for running the service.
Module name decomposed D: \java\test\jsl_0_9_9r\Release\ jsl64 .exe
Ini file path final D:\java\test\jsl_0_9_9r\Release\jsl64.ini
Final ini file decomposed D: \java\test\jsl_0_9_9r\Release\ jsl64 .ini

Initalization file: D:\java\test\jsl_0_9_9r\Release\jsl64.ini
stringbuffer=16000
logtimestamp=%Y-%m-%d
logfile=
failureactions_resetperiod=300000
failureactions_rebootmsg=Server going down due to Java service failure
failureactions_command=HelloWorld -seriously
failureactions_actions=0
cmdline=-cp D:\java\test\jsl_0_9_9q\src com.roeschter.jsl.TelnetEcho
jrepath=
jvmtype=server,client,hotspot,classic,jrockit
jvmsearch=path,local,registry
jreSearchPath=1
jreSearchLocal=1
jreSearchRegistry=1
jvmversionallowed=ANY
dependencies=
dependency=
starttype=auto
account=(null)
password=(null)
loadordergroup=someorder
wrkdir=D:\java\test\jsl_0_9_9r\Release\
appname=TelnetEcho
servicename=TelnetEcho
displayname=TelnetEcho
servicedescription=Description for Telnet Echo
stdout=
stderr=
stdoutappend=no
stderrappend=no
systemout=
systemerr=
systemoutappend=no
systemerrappend=no
interactwithdesktop=no
exceptionerrorcode=0
onexiterror=ignore
reportservicestoppedonmainthreadexit=no
stopclass=java/lang/System
stopmethod=exit
stopsignature=(I)V
stopparams=
pauseclass=
pausemethod=
pausesignature=
pauseparams=
contclass=
contmethod=
contsignature=
contparams=
confirmrunclass=
confirmrunmethod=confirmRunning
confirmrunsignature=()V
confirmrunparams=
premainclass=
premainmethod=run
premainsignature=()I
premainparams=
stopport=0
startdelay=0
useconsolehandler=false
path=
modulepath=
export=
-cp
D:\java\test\jsl_0_9_9q\src
Expanded classpath=D:\java\test\jsl_0_9_9q\src
com.roeschter.jsl.TelnetEcho
Java command line:
java -Dservice.stop.port=0 -Dservice.path=D:\java\test\jsl_0_9_9r\Release\ -Dservice.name=TelnetEcho -Dservice.inifile=D:\java\test\jsl_0_9_9r\Release\jsl64.ini -cp D:\java\test\jsl_0_9_9q\src com.roeschter.jsl.TelnetEcho

StartServiceCtrlDispatcher being called.
This may take several seconds.  Please wait.

Adjust the classpath setting in the ini file.

Telnet echo will run a primitive telnet server which is a simple echoing back any character you type. Test it by running your favorite telnet terminal against your localhost.

Next install the service with jsl -install.

Test again and try to shut it down in the service manager.

Uninstall with jsl -remove.

Release Information

Release policy

This product receives regular update, feature enhancements and bugfixes. Every 12 months I produce a release though I will most probably never do a 1.0 release. I will support new JDKs and Windows versions. If you report bugs or show stoppers for your project I will generally try to fix them as soon as possible (usually on the next weekend).

Platforms

32bit and 64bit JREs and JDKs are supported. JSL should work with Windows 7 and later (last tested version is Windows 10). No recent tests have been performed on Windows XP or older The JVM type parameter (-classic -hotspot -client -server ) which allow for a VM selection on command line is supported.

JVM

Supported JAVA versions are JDK/JRE 1.2 onwards.

All varieties of the virtual maschine should work (classic, JIT, hotspot, server). I will support future versions of the JDK as soon as they are betas available. If you would like other JVMs supported please send me a note with a link where I can get the JDK.

Vendor

Has been tested with OpenJDK based JDKs like Azul Zulu, and Oracle's JDK. JSL has also been used with IBMs J9.

Executables

Since 0.99s all executables are statically linked

jsl.exe 32bit

jsl64.exe 64bit

jsl_debug.exe 32bit

jsl64_debug.exe 64bit

Support

Any and all feedback is welcome. New features will only be added and bugs removed if you report them to me. Simple things can be done in a day (if I have time). But don't be surprised if I reply: "Nice idea, don't have time now."

I will happily provide e-mail support and feedback as long as you acknowledge that I'm a hard working member of our society. I can't guarantee a 2 hour response time and won't care for requests like "Help, my project is due tomorrow and I will in trouble if I can't get the service running under Vista". You may phone me, if this channel is more appropriate to discuss the issue at hand. My timezone is Central European. From Monday to Friday I'm generally on the road and might or might not have time, but you can always try on weekends.

Change Log and Archived Versions

Release 0.99x (December 2021) Will now find Adoptium in the Registry. Setting the working directory (wrkdir) earlier in the startup cycle so that all logs with relative paths will go there . Tested with Java 17.

Release 0.99w (January 2020) Better support for identifying various JVMs in the registry, in particular AdoptOpenJDK. Tested with Java 13.

Release 0.99v (August 2019) From this version onward JSL is compiled with Visual Studio 2019 Fixes a bug introduced with version 0.99r, where the service would not start because JSL can not attach to a console window of the parent process. This error is Windows version dependent. You may not notice the error, but it is recommended to upgrade to this version.

Release 0.99u (May 2019) Tested with JDK 11. Tested with Azul, Oracle, AdoptOpenDK, Corretto and J9. Will find Azul, AdoptOpenJDK, J9 and Oracle in the registry for all Java versions up to Java 17. Will find JRE and and JDKs in the registry. Added options for fine grained control over which JVM type to find in the registry (JRE, JDK, Azul, Oracle). Switched to Visual Studio 2017.

Release 0.99t (May 2018) Tested with JDK 10 release.

Security fix for CVE-2014-5455 The executable path in the service registry is now always placed in quotes.

Release 0.99s (December 2017) Tested with JDK 9 release. Note that JDK 9 only works with the statically linked version. From this version onward JSL is compiled with Visual Studio 2017 and statically linked. I have therefore removed the dynamically linked executables. All executables are statically linked from now on. Adjusted and documented JVM version strings and registry keys.

Cleaned up the process of finding a JVM in the registry, now respecting the jvmversionallowed parameter (please check sample ini file). Supports finding Zulu in the registry. Supports finding Java 9 in the registry. If searching in the registry is enabled the jvmversionallowed parameter is now used to filter for versions. It will start matching the first entry in the allowed list and then continue down the list till it finds a matching version.

Debug logs can now be enabled through setting the environment variable _JAVA_LAUNCHER_DEBUG.

Release 0.99r (July 2017) New feature: Option to configure if a console windows show in javaw style. "jsl.exe -runapp" starts application without console. "jsl.exe -run -console hide|parent|new" gives detailed control over the console.

Cleaned up behavior of the jvmtype parameter and made failure to find a JVM more verbose. Default is to try all types of JVM in the sequence: server,client,hotspot,classic,jrockit. Fixed bug reading the "stringbuffer" parameter - always reading default value.

Release 0.99q (January 2017) From this version onward JSL is compiled with Visual Studio 2017 New feature: Optionally constrain the JVMs and JVM versions through the parameters jvmversionallowed and jvmsearch. This allows to define a specific JVM version to be used. Or avoid registry discovery of default JVMs by specifying in which locations JVMs are searched for.

Release 0.99p (December 2015) Tested with JDK 1.8 release and JDK 1.9 preview. Tested with Windows 10. Fixed a bug where jsl -install <ini file> would not recognize the ini file. New features: Supports configuration of common service failure actions in the .ini file. Log file name configurable (debug and error logs). See "logfile" in ini file. JSL now terminates if log file cannot be openend. Logfile optionally timestamped/rotated. See "logtimestamp" in ini file.

Release 0.99o (August 2013) Tested with JDK 1.8 preview. Fixes a bug where the configuration files could not be located in an UNC path (e.g. \\server\app\jsl.ini). Fixes a bug in wildcard expansion where wildcard expansion would not respect the wrkdir setting. Wrkdir in now set before wildcard expansion. Fixes a bug where random exit codes were reported by the service.

Release 0.99n (September 2011) Fixes a bug in the wildcard path expansion.

Release 0.99m (June 2011) Tested with JDK 1.7 (64bit Windows 7). New feature, a callback (confirmrunning) which starts a background thread before the main method. Only when this thread returns the service will be reported as running to windows. This can be used for smarter dependency management. Fixes file handling bug when logging was activated (race conditions). Fixes a small bug where jsl.exe -install jsl.ini would not work because it expected absolute paths only. Now works with all kinds of relative paths.

Release 0.99l (December 2009) Two small changes which are useful for people redistributing JSL with automatic installers. Multiple jvmtypes can be specified now. E.g. jvmtype=server,client such that JSL will fall back to the "client" JVM if the "server" JVM is not available. JSL will now report a command line return code of "1" if jsl -install/configure/remove fail. In case of succes its "0".

Release 0.99k (October 2009) New Version finally supports 64bit JVM. Tested on Windows 7 64bit. Use jsl64.exe or rename to your preferences. From this version onward JSL is compiled with Visual C++ 9. This introduces a dependency to msvcrt90.dll. If you dont have msvcrt90.dll installed please use the statically linked version or use the jsl_VC6.exe (32bit only) compiled against Visual C++ 6.0 as in earlier versions of JSL. Bugfix: JSL ini paths can now contain spaces even when passed explicitely on the command line (this was only a bug in very special circumstances). Fixed the issue with JSL requiring msvcr71.dll but the DLL not being in path. This is a Java problem in 32bit JVM and Sun fixes it by placing the DLL in the JRE\bin folder. JSL simply extends the path once the JRE location is identified. Fixed an interact with desktop issue. JSL is no setting it correctly using the CreateService call. Note the comment in the .ini file Added feature where environment variables are looked up in the registry as a fallback. This removes the requirement to restart the server in some cases.

Release 0.99j (January 2009) Variables defined in the .ini files [define] section can now be exported to the environment. The new "export" parameters in the [define] section contains a comma separated list of variables to be exported (e.g. export = PATH,CLASSPATH ). The "wrkdir" parameters treats paths starting with a "." special. As a service has no shell from which to inherit a default working directory a "." was not a valid path so far. From this version the "." in the wrkdir (and only there as all other paths will be relative to the wrkdir) will be substituted by the directory in which the .ini file resides.

Release 0.99i (August 2008) This version adds the much requested feature of setting the "interact with desktop" flag in the service configuration through the jsl.ini file at installation time (interact_with_desktop). Simple string array (String[]) parameter lists can now be passed to stop, pause and continue calls. The parameter list is in stopparams (cmd line style delimited by spaces and quotes). Of course the signature must be correct ( stopsignature=([Ljava/lang/String;)V ).

Release 0.99h patch 1 (July 2008) This version fixes a bug in the java command line parser (cmdline), a new feature in version 0.99h. This bug will NOT affect you if you pass the java command line the traditional way in the "paramxx" parameter. If you do not want to upgrade there is also a workaround available: Enclose the last parameter in the java command line in quotes. (e.g. -cp c:\test "my.java.test"). The bug would create "phantom parameters" by parsing beyond the end of the command line if there was data in memory by change beyond the terminating zero of the command line string.

Release 0.99h (June 2008) Supports class path expansion (JDK 1.6 feature). As the class path substitution is not actually a Java feature, but a feature of the Java launcher, JSL supports it with all Java versions. Longer buffer for configuration parameter handling. If it is still not sufficient adjust the "stringbuffer" parameter. Allows for variable definition in the [defines] section of the .ini file. Works like you would expect from a batch file. Environment variables can still be used or overridden in this section (PATH=%PATH%;mypath). Start parameter can now be entered in Java command line style in the "cmdline" parameter. JSL will break the command line down respecting spaces in quoted strings. Supports setting the service description in the "servicedescription" parameter.

Release 0.99g (June 2007) Tested with JDK 1.6. Very few other changes. Only produces a warning if the JVM version is not known. Previously this created an error. Will produce debug output even in release version if the -debug option is used on command line. Included debug version into distribution. Added a few debug statements to make it more verbose on how and where it found the JVM.

Release 0.99f (Oct. 2004) Will run with JDK 1.5. Tested on Win XP. New jvmtype parameter to replace -server/-client parameters and to allow other jvm implementation binary directories. Passes the full path to the .ini file as an -Dservice.inifile parameter to the JVM. Added a helper class (com.roeschter.jsl.WindowsCompatibleProperties) to read it as if it where a Java properties file. Added support for a "pre main" call. A static method which can be called BEFORE the main method on the Java command line. Allows you to run code before the actual application is called. E.g. to install debug hooks.

Release 0.99e (Aug. 2003) Tested JSL with Windows Server 2003. Extended and documented a hidden feature. Any file passed in the -install and -configure options will used for running the service. It will be trivially appended to the service execution command with the -ini option. The feature of calling with the -ini option was there all the time but not documented. This makes is possible to run several service from the same executable with diffrent configuration files.

Release 0.99d (Feb. 2003) Added append option for stdout redirect. Added an option (reportservicestoppedonmainthreadexit) that allows for cleaner shutdown behaviour in certain situation where System.exit() is not called. Changed the linkage from static to dynamic (linking MSVCRT:DLL). This is consistant with the way the JVM does its linking and it results in a smaller executable. An old staticcally linked executable is still there for backwards compatibility.

Release 0.99c (Dez 2002) Support for redirecting stderr, stdout, Java System.out and System.err is now working. Previously only C stdout and stderr got redirected properly. Please see example jsl.ini for more details. Fixed a minor bug, which created problems when there where spaces in the path to the executable.

Release 0.99b (May 2002)Support for environment variable substitution in config file. Normal Windows style subsitutions will work e.g. %PATH%. Moved helper classes into a package due to JDK 1.4 compiler having problems with default package. Support for pause and continue service manager events. You can simulate and test service stop, pause and continue behavior on the command line by starting with -debug option. Use CTRL-C for stop service, CTRL-BREAK will toggle between pause and continue service.

Release 0.99a (Jan. 2002) Support for redirecting error and output stream to a file. All Java output to System.out and System.err will end there. The kind of error reported to the service manager is now configurable. Non zero error code from the JVM can be configured to be ignored, to be reported back or to result in fatal termination (from the viewpoint of the service manager). Some users requested the later behaviour as it allows for sophisticated WIN2000 service recovery strategies to be triggered by a simple System.exit(1). The location of the executable to be registered as the service can be defined in the .ini file. The location of the .ini files can be passed on the command line. This feature allows for more flexibility in install scripts if multiple services are to be installed.

Release 0.99 (Sep. 2001) Support for stopping JAVA program through a direct call to static method through JNI (in the simplest case a System.exit() ). Tested with IBM JDK 1.3. Supports setting the environment PATH of the service.

Release 0.98 Internal version.

Release 0.97 (June 2001) Supports JDK 1.4. New -run option that does not pass the -Dservice properties. Console window is now switchable with the useconsolehandler option (see jsl.ini example).

Release 0.96 (March 2001) nasty bug, which erronously reported unexpected process termination in Win2000 has been removed.

Release 0.95 (March 2001) supports service dependencies. New -configure option to reconfigure the service settings without deinstalling it. The JRE environment can now be configured in the jsl.ini file. A description on how a JRE is selected is given in the FAQ. User account and password to start the service are now configurable. Service start type is configurable.

Release 0.94 (July 2000) works around the infamous LOGOFF bug which stopped the Hotspot VM when a user logged off. I use a workaround which installs a ConsoleControlHandler after
the JVM has been initialized but before the main() method is called. Tested on Win NT 4.0 and Win 2000.
The special parameters (-classic -hotspot -server ) which allow for a VM selection on command line are now supported.
The demo classes and ServiceStopper classes are provided as a .jar archive for ease of use.
The ServiceStopper Thread is started as a deamon Thread for cleaner shutdown.

Release 0.93 (June 2000) will now run with JRE 1.3 release

Release 0.92 (Feb. 2000) will now run with JRE 1.3 beta

Release 0.91 (Feb. 2000) is now debugged against Win 2000. Microsoft subtly changed the StartServiceCtrlDispatcher API call. Null is no longer a valid parameter for a service name. NT 4.0 API states that the service name will be ignored if service is of type SERVICE_WIN32_OWN_PROCESS.

Release 0.9 (Feb. 2000) contained a serious bug. To be precise it would not run (I apologize to all who tried).

Release 0.5 (June 1999) First public release

FAQ

My Java program won't start.

Run JSL in debug from command line using jsl -debug. Create some debug output in your Java program. Only if things are fine in debug mode install it as a service.

One common issues is mounted network drives, which are not visible from a service. Use UNC path instead (//server/path).

JSL says "Did no find any JVM in any search locations" or "Error trying to locate any of the JVM types listed below"

Please check the documentation for jrepath,jvmtype,jvmsearch,jvmversionallowed. Or set them to default by comenting them in the .ini file and run the debug version. Then speficy the JVM location explicitely with jrepath.

JSL searches for the JVM in a number of locations by default. The path specified in jrepath,in a subdirectory or as sepcified in the registry. In debug mode the log file will list where its looking and failing to find a java.dll.

Once a JVM has been located a JVM Type needs to be selected. Nowadays this is either client or server. Both should be found by default.

JSL provides you full control where the JVM is searched for, which JVM Types are accepted and which JDK versions can be used. If you have set any of those parameters to non default values, please check again one by one to isolate why no suitable JVM could be

JSL fails to start, reporting the a DLL is missing.

The plain jsl.exe, which is a bit smaller is dynamically linked you will need a few Microsoft Visual C libraries, which most likely are already on your system. If you see problems, try the statically linked executable which has no such dependencies.

When do I need 32bit and 64bit versions?

You need a 64bit OS to run 64bit JSL, but you can also run the 32bit version on a 64bit OS. The 64bit JSL starts the 64bit JVM and the 32bit JSl run the 32bit JVM.

Which Java Runtime Environment is used when I start the jsl?

JSL attempts to find the JRE in the following location in the order given. For details check java_md.c

  1. It reads the jrepath parameter from the configuration file
  2. It loks for a java.dll in the bin directoy colocated with the jsl.exe
  3. It loks for a java.dll in the jre\bin directoy colocated with the jsl.exe
  4. It looks for JRE path in the registry

How can I make sure the JAVA application is restarted after it fails

JSL doesn't care about this, but Windows (Server) comes with tools to monitor and automatically restart service. Those tools will usually rely on the service return code to decide if the shutdown was normal or abnormal. JSL has a number of settings to pass the the java exit code or to react to exception in appropriate ways.
See 'exceptionerrorcode' and 'onexiterror' settings in the configuration file.

The program did run fine in debug mode but can't find files when run as a service

Don't rely on the standard path when locating files from the service. Always use absolute paths. The service will find it's start path through a java system property. You can use environment substitutions now but be careful and make your first tries without them.

How can I find out from which directory the service was started and how it is named

The JVM is started with a command line similar to this one.

		java -Dservice.stop.port=8465 -Dservice.path=E:\Java\TEST\jsl_0_9\Debug\ -Dservice.name=TelnetEcho -cp e:\java\test\jsl_0_9\TelnetEcho
        

The -D options can be accessed through the System Properties. Look in class java.lang.System for details.

The program did run fine in debug mode but still does not find the files it needs though I load them from an absolute path.

Drives mounted from a network device are not accessible from a service! Access them through fully qualified network names.

E.g. \\myserver\myfiles\myservice\hello.data

The program did run fine in debug mode but is denied access to the network shares I need

In standard settings the service will run as a system user. Sytem user can't access the network. You need to change the security settings manually in the NT service manager. There may be other more exotic errors which could result from this.

The service runs fine but I can't stop it. Service manager tells me the stop request failed and I can't stop it using the task manager.

Services can not be stopped forcedly (except with a debugger). They must stop themselves. That's what the JNI calls into the running JVM are for. Please see the HowTo guide or the configuration guide and look for "stopmethod". To get rid of your service you must either restart Windows (after you set service starting mode to manual) or use a Debugger to attach to and kill the service.

Links

Service Wrappers for Java

Azul Zulu JVM

Oracle Java

IBM J9

License

Java Service Launcher is Public Domain.

This means the software is FREE. Free means you may use or reuse any part of the software. You may package it with commercial software and use it in commercial and business environments. You may NOT claim copyright for the JSL software and it's source code or any parts of the software and source. Any derived work may retain a copyright or be commercialized as long as the JSL parts of it are not covered by this copyright.

You may distribute derived work in executable form and not include the JSL source code if JSL constitues only a minor part of the intellectual work (in other words, you can take the executable and embed it in a Java application you distribute commercially), but you may not charge in particular for or discriminate against the use of the parts derived from JSL.

Some pieces of the JSL source code come from MSDN and SUN/Oracle Java launcher examples. As far as I can see Microsoft and SUN/Oracle have granted developers acknowledging their copyright the permission to create redistributable binaries from those sources. If you want to extend the JSL source code I recommend you acknowledge the MSDN and SUN/Oracle license conditions. You probably have done so anyway by downloading Java and using VC++.

Disclaimer: This software is supplied AS IS with not claim of fitness for purpose. Sources are supplied for informational purposes for the experienced developer.

Documentation

Command Line

Calling jsl.exe without parameters gives an overview of the available options.

-install

Install the service in the NT service manager. Service is not started immediately, though it will start automatically when NT is rebooted.
Start the service from command line with NET START <APPNAME>.

-configure

Will reconfigure from the current configuration file

-remove

Remove an installed service. This may fail if the service is still running.
Stop the service from command line with NET STOP <APPNAME>.

-debug

Run the application from command line for debugging purposes. A service need no be installed.

You can simulate and test service stop, pause and continue behavior on the command line by starting with -debug option. Use CTRL-C for stop service, CTRL-BREAK will toggle between pause and continue service.

-run

Run the application from command line for test. Should behave like running the program with java.exe

-runapp

Run the application from command without console. Useful for starting graphical applications. Note that you will not see ANY output unless you redirected stdout/stderr or run in debug mode, which logs to a file.

-console hide|attach|new

Optional parameter to produce javaw like behavior. "-console hide" will not open a console and not show any output. "-console attach" (default) will attach to the current console, usually the command prompt. "-console new" will open a new console and show all output there.

Full command line options

jsl.exe -install|configure|remove|run|runapp (<ini file>) (-console hide|attach|new)

Configuration File

Sample Configuration

Simple Configuration File

jsl_minimal.ini

[service]
appname = TelnetEcho
servicename = TelnetEcho
displayname = TelnetEcho
servicedescription = Description for Telnet Echo

useconsolehandler=false

stopclass=java/lang/System 
stopmethod=exit 
stopsignature=(I)V

logtimestamp = "%%Y-%%m-%%d"

[java]
;jrepath=d:\java\jdk18_64
wrkdir=.
cmdline = -cp . com.roeschter.jsl.TelnetEcho

Full Configuration File

jsl64.ini

[defines]
;This section defines variables, which can be used elsewhere in the ini file
;A variable refenrencing itself e.g. "PATH=%PATH%;c:\java\test" will result in an import from the environment. 
;JSL will first look in the normal environment then in the system environment of the registry as a fallback.
;Any variable not in the defines section will result in a environment lookup as well.
;Variable substitution is possible in any value in the ini file
;% is escaped by %%
;PATH= %PATH%
;JAVA = %JAVA_HOME%
;P1 = d:\java\test\jsl_0_9_9p
;P2 = %P1%

;Comma seperated list of variables to be exported to the environment
;Supersedes the "path" parameter further down. 
;Do not use the path parameter if you also set "PATH"in the export parameter as precedence is undefined.
;export = CLASSPATH,PATH

[service]
appname = TelnetEcho
servicename = TelnetEcho
displayname = TelnetEcho
servicedescription = Description for Telnet Echo


;Size of internal buffer for string handling
;increase if you use very long command line parameters e.g. a very long classpath
stringbuffer = 16000

;OBSOLETE but supported
;port used to communicate stop command to JVM 
;Must be unique for each JSL instance installed
;This option is ignored if a stop method is defined further down
;stopport = 8465

;delay n milliseconds to start the Java VM
;Default is no start delay
;startdelay = 10000

;service dependencies can be added
;as a comma separated string "dep1,dep2"
;dependencies=depend2

;service start type
;auto demand disabled	
;default is auto
starttype=auto

;Allow interaction with desktop
;This is a service configuration flag; default is false
;interactwithdesktop = false

;load ordering group
loadordergroup=someorder	

;account under which service runs
;default is system
;account=mroescht-PC\mroescht

;password for above account
;system need not provide a password
;obfuscation of password is not supported. It is actually not needed.
;The password specified here is ONLY used during the jsl -install command. It can (and should) be deleted after installation.
;password=somepwd

;Allocate a console and register a console event handler to catch shutdown events.
;Default is true; options are FALSE TRUE false true YES NO yes no
;This option has two effects:
;1. If active it catches the logoff events and prevents the service from erroneously stopping in this case.
;2. It creates a console window if interaction with the desktop is allowd.
;Effect 1 can be achieved in Java 1.3.1 and higher by using the -Xrs option.
;Effect 2 may or may not be desired.
useconsolehandler=false

;Call . through JNI so stop the JVM.
;This can be used an alternative to the ServiceStopper 
;When all three parameters are defined the JSL will try to use JNI to stop the service. 
;If not it will use a tcp/ip connection to the stopport.
;The simplest way to use this functionality is to use the Systen.exit() call as specified below. 
;Nevertheless you can call any static method in your code.   
;The method called is expected to terminate the JVM one way or the other. It can directly 
;call System.exit() or make another Thread do it make the main method return. 
;The method can return imediately if desired. If the JVM doesn't stop another attempt can be made to 
;stop the service at a later time.
stopclass=java/lang/System 
stopmethod=exit 

;Take care to specify the right signature for your method. void System.exit( int code ) has 
;the sifnature specified below. void myMethod() has the signature ()V. Please refer to the
;JNI documentation for details.
stopsignature=(I)V

;Parameters can be passed in "stopparam". 
;Note that parameter passing is only implemented for the special case that the signature of the 
;method is (String[]). Generic parameter passing is cumbersome to implement in C so I choose
;to implement only the most common case.
;stopsignature=([Ljava/lang/String;)V
;The parameter list is parsed into an array. Delimiters are spaces or quoted strings.
;stopparams=STOP "OR NOT STOP"

;Name and signature of service pause method. Will be called on a SERVICE_CTRL_PAUSE event.
;Please note that unless you have configured all pause and continue arguments 
;you will not see the pause button enbaled in the service control manager GUI
;pauseclass=com.roeschter.jsl.TelnetEcho
;pausemethod=pause 
;pausesignature=()V
;pauseparams=

;Name and signature of service continue method. Will be called on a SERVICE_CTRL_CONTINUE event.
;Please note that unless you have configured all pause and continue arguments 
;you will not see the pause button enbaled in the service control manager GUI
;contclass=com.roeschter.jsl.TelnetEcho 
;contmethod=cont 
;contsignature=()V
;contparams=

;Value of the PATH environement variable being set by the service. 
;PATH will remain unchanged if this is empty.
;path=c:\util

;Redirect C level stdout and stderr to the specified files
;Please note that those are diffrent files then the ones used below for 
;Java level stdout and stderr
;Default is no redirection
;Use the pattern below to timestamp/roate log files. Please note the %% escapes
;Applies to stdout and the debug logfile. If not present there will be no log file rotation.
logtimestamp = "%%Y-%%m-%%d"
;stdout=c:\temp\stdout.log
stdoutappend=no
;stderr=c:\temp\stderr.log
stderrappend=no
;redirect log to file for errors and debugging - you will only see output here if debugging is enabled
;Use debug version or set _JAVA_LAUNCHER_DEBUG environment variable
;logfile = C:\temp\jslmy.log

;Forces debugging mode
;Default is false
debug=false

;Redirect JAVA level System.out and System.err to the specified files
;This simply sets new output streams for System.out and System.err after
;the JVM is initialized but before the main method is called.
;You might find that this option has no effect at all for some applications, as the 
;JAVA application is of course free to redirect System.out and System.err 
;to some other log mechanism.
;Default is no redirection
;Default is to overwrite file
;systemout=c:\systemout.log
;systemoutappend=no
;systemerr=c:\systemerr.log
;systemerrappend=no

;Explicitely call this method and wait for it to return before setting the service to status running
;This method will be called before the main method
;After we call this method the service will only be set to SERVICE_RUNNING once it returns 
;This is started in a seperate thread and will not prevent the main method from being called
;Uncomment the confirmrunclass to enable
;confirmrunclass=com.roeschter.jsl.TelnetEcho 
confirmrunmethod=confirmRunning 
confirmrunsignature=()V
confirmrunparams=

;This method will be called before the main method of the start class specified on command line 
;but after the JVM is fully initialized and stdout and stderr redirection have been performed.
;This method must return! It is called from the same thread as the main method.
;In order for the normal JVM start behaviour to continue this method must return 0.
;It may legally return any other value or throw any exception, which in both cases will result in
;a regular termination of the JVM much in the same way as if an uncatched exception had been thrown
;in the main method.
;It may legally start other threads in the JVM, which will behave in the same way as started from
;the main method.
;In fact you will be able to produce pretty much the same behaviour as calling the static method first in
;your main method.
;The example method present here is a scheduler which will in turn run the code specified 
;in its modules list. Some utilities are provided.

;Uncomment the premainclass to enable
;premainclass=com/roeschter/jsl/PreMainScheduler
premainmethod=run 
premainsignature=()I
premain.modules=threaddump

premain.threaddump.class=com.roeschter.jsl.ThreadDumpListener
premain.threaddump.method=start
premain.threaddump.wait=3000
premain.threaddump.critical=no
premain.threaddump.interface=127.0.0.1

;Report service stopped on exit of main thread
;you might want to set this to yes if your service terminates "silently"
;It is recommended that a service is stopped by calling System.exit() at some time, 
;either externally or internally. This provides a nice and clean shutdown hook.
;If the service terminates silently by just ending the last thread this might result 
;in the service manager not recognizing the fact and denying restart. Use yes in this case.
;It should usually be safe to use reportservicestoppedonmainthreadexit=true
;even if you use other threads then main. The shutdown code will wait for non daemon threads to stop
;I can't remember why I made this parameter optional. It must have been useful for some people or in some situations
;Default is no
;reportservicestoppedonmainthreadexit = no

;Behaviour in case of JVM exiting with an error 
;Define whether an execption in the main method should be considered an error
;Use this exit code in case of an exception.
;exceptionerrorcode=0

;Desired behaviour for a non zero exit code (including exceptions as specified above)
;Options:
;ignore 		terminate without error (default)
;returncode 		exit with error code reported by the JVM to to the service manager
;fatal			don't report regular service stop to service manager making it believe 
;a fatal error had occured in the service (this is sometimes desirable if fatal error 
;recovery mechanisms are in place)
;onexiterror=fatal

;Use this executable for registering the service.
;Default is the executable used for installation
;modulepath="e:\java\test\jsl_0_9_9e\release\jsl.exe"


;Configures the the Windows service failure actions.
;The below is not JSL functionality, but rather Windows Server functionality, which can be overridden by the server administrator.
;You need to configure exceptionerrorcode and onexiterror as of above to create the expected behavior
;Configuration will be made at install time (jsl -install). 
;For changes to become effective you need to reconfigure JSL (jsl -configure)
;See MSDN for details: https://msdn.microsoft.com/de-de/library/windows/desktop/ms681988%28v=vs.85%29.aspx
;
;The service control manager counts the number of times each service has failed since the system booted. 
;The count is reset to 0 if the service has not failed for ResetPeriod seconds. 
;When the service fails for the Nth time, the service controller performs the action specified in element [N-1] of the actions array. 
;If N is greater than cActions, the service controller repeats the last action in the array.

;The time after which to reset the failure count to zero if there are no failures, in seconds. 
;Specify INFINITE to indicate that this value should never be reset.
failureactions_resetperiod=300000
;The message to be broadcast to server users before rebooting in response to the SC_ACTION_REBOOT service controller action. 
failureactions_rebootmsg="Server going down due to Java service failure"
;The command line of the process for the CreateProcess function to execute in response to the SC_ACTION_RUN_COMMAND service controller action. 
;This process runs under the same account as the service. 
failureactions_command="HelloWorld -seriously"
;The number of elements in the lpsaActions array. 
;Settings 0 deactivates. Non configuring enough  action_type and action_delay wil result in JSL issueing an error. 
failureactions_actions=0

;SC_ACTION_NONE 		0	= No action.
;SC_ACTION_RESTART		1	= Restart the service.
;SC_ACTION_REBOOT 		2	= Reboot the computer.
;SC_ACTION_RUN_COMMAND	3	= Run a command.
action0_type=1
;The time to wait before performing the specified action, in milliseconds.
action0_delay=10000 	

;Setting failureactions_actions=4 will result in the following behavior:
;Service restart will be tried 3 times with 1 10s delay each. On the 4th failure the server will rebooting
action1_type=1
action1_delay=10000 
action2_type=3
action2_delay=10000 
action3_type=2
action3_delay=10000 


[java]
;Path to the java runtime used
;If this option is not used the default from the registry will be used
;jrepath=D:\java\jdk18_64
jrepath=D:\java\zulu10_64

;Type of jvm to be used. Alternative mechanism to specifiying -client or -server on the command line.
;Can use any JVM name, which is diffrent from the command line which will only allow -client and -server
;Useful when using a JVM diffrent from Suns implementation.
;Jvmtype can be a comma seperated list. JSL will first find a JVM installation location. THEN it will load the first 
;type of jvm in the list it can find. It will NOT search in alternative JVM locations for alternative jvm types. 
;Be careful what JVM is actuallay installed and used before you report a bug on this feature.
;Default is "server,client,hotspot,classic"
;jvmtype=server,client,hotspot,classic
;jvmtype=server

;Locations to search for the JRE
;Comma seperated list
;Default is search everywhere : path,local,registry
;path=Use the location specified in the jrepath option above
;local=search for a jvm co-located with JSL (in a subdirectory \bin or \jre\bin)
;registry=Find a JVM in the registry (First Zulu and Oracle Java 9+, then Zulu and Oracle Java 8 - matching against jvmversionallowed)
jvmsearch=path,local,registry

;Searching for various types of JVM in the registry
; registryfindjre=yes
; registryfindjdk=yes
; registryfindazul=yes
; registryfindoracle=yes
; registryfindj9=no //Uses the same registry keys as Oracle. Equivalent to registryfindoracle
; registryfindcorretto=yes  //Currently inactive corretto does no register in registry
; registryfindadoptopenjdk=no //Uses the same registry keys as Oracle. Equivalent to registryfindoracle

;Allowed JVM versions
;Comma seperated list - substring matches - e.g. 9.0 matches 9.0.1.1
;Java 2 to Java 8 version string are "1.2.x" ... "1.8.x" 
;Since Java 9 the version string is "9.0.x.y"
;Azul Zulu uses version string "8.x.y.z" in the registry - you may need to specify "8,1.8" to allow both registry and version string match to pass 
;Default is: ANY 
jvmversionallowed=ANY

;working directory
;If the working directory path starts with a "." it will be replaced with the .ini directory path
;This is neccessary because a service does not inherit a working directory from the shell. Therefore "." would be meaningless.
;This logic for "." is only required for the wrkdir bas all other paths will resolve a "." against the working dir once it is set.
;wrkdir=c:\java\test\jsl_0_9_9r\release
wrkdir=.

;The java command line
;The entry method below using a parameter list still works but the command line variant is more convenient.
;Everything separated by whitespace on a java command line is broken down into a parameter here. 
;You don't need to care about quotes
;around strings containing spaces here. e.g. 
cmdline = -cp "D:\java\test\jsl_0_9_9t\src" com.roeschter.jsl.TelnetEcho


;OBSOLETE but supported alternative for passing parameters. 
;May be useful if you are generating this file programatically.
;the number of paramters passed to the java application 
;parameters must be named param00, param01 ...
;Please note that each command line parameter has to go on it's own parameter value here!
;The JVM expects a preparsed array of parameters.

;params = 3
;param00 = -cp
;param01 = D:\java\test\jsl_0_9_9r\src
;param02 = com.roeschter.jsl.TelnetEcho

;params = 7
;param00 = -cp
;param01 = c:\java\test\jsl_0_9_9g\src
;param02 = -Dcom.sun.management.jmxremote
;param03 = -Dcom.sun.management.jmxremote.port=9696
;param04 = -Dcom.sun.management.jmxremote.authenticate=false
;param05 = -Dcom.sun.management.jmxremote.ssl=false
;param06 = com.roeschter.jsl.TelnetEcho