Note: information in this Chapter is not applicable to the Standard Edition of Excelsior JET.
A Windows service, formerly known as NT service, is a special long-running process that may be launched during operating system bootstrap. An essential feature of a service is the ability to run even if no user is logged on to the system. Examples of services are FTP/HTTP servers, print spoolers, file sharing, etc.
Services are supported only in the Microsoft Windows NT/2000/XP operating system product line (Windows 95/98/ME do not support services).
Typically, Windows services have not a user interface but are managed through the Services applet of the Windows Control Panel, or a separate application or applet. Using the standard Services applet, a user can start/stop, and, optionally, pause/continue a previously installed service. The common way for a service to report a warning or error is recording an event into the system event log. The log can be inspected using the Event Viewer from Administrative Tools.
A service program is a conventional Windows executable associated with a unique system name using which it can be installed to/removed from the system. A service can be installed as automatic (to be launched at system bootstrap) or manual (to be activated later by a user through the start button in Control Panel/Services).
JET eases conversion of programs written in the Java programming language into Windows services through providing the custom Excelsior WinService API and the required support in the compiler and the run-time system.
This section covers practical use of the Excelsior WinService API. The complete API reference is available in your JET installation as doc/index.html.
A Windows service program must register a callback routine (so called control handler) that is invoked by the system on service initialization, interruption, resume, etc. With JET, you achieve this functionality by implementing a subclass of com.excelsior.service.WinService and specifying it as the service main class in your project. The JET runtime will instantiate that class on startup and translate calls to the callback routine into calls of its respective methods, collectively called handler methods below:
| init | service initialization |
| run | main service body |
| stop | stop notification |
| pause | pause notification |
| resume | resume notification |
| shutdown | system shutdown notification |
The init method is invoked at the moment of service activation. It returns a boolean indicating whether the pause/resume control requests are accepted by the service. If init has completed in time (see Setting timeouts), the run method is invoked immediately. Otherwise a warning message is logged into the system event log and the run method is invoked.
The run method implements the main service functionality. Upon return from that method, the service stops.
When the user selects the service in the Control Panel/Services applet and clicks the Stop/Pause/Continue buttons, the respective handler methods are called.
The base class WinService implements all handler methods as doing nothing, so if your service does not support pause/resume and does not need any initialization or cleanup on start/stop/shutdown, you may override just the run method in your WinService subclass:
public class MySrv extends com.excelsior.service.WinService
{
public MySrv() {
/* default constructor must be present */
}
public void run () {
logInfoEvent ("MySrv service has started");
/* Main service logic here */
logInfoEvent ("MySrv service has stopped");
}
}
Note: As the JET Runtime instantiates such a class automatically, using the method Class.newInstance(), the default constructor with an appropriate access modifier must be present.
The getArgs method returns an array of strings containing the command line arguments specified on service startup.
The run handler is long-running and thus is not limited in time. Other handler methods are required to complete within a particular time frame. The default timeout value is set to 10 seconds, however, init, stop, pause, and resume handlers can prolong the period of their execution by calling the respective method. The timeout for the shutdown handler is defined by the system (as less than 20 seconds) and cannot be adjusted.
Consider an example how the init handler is executed. Let a service be activated and the init handler be invoked. Suppose init has run for 9 seconds and then calls setInitTimeout(5000). As a result, init can execute for up to 14 seconds.
If the method init is not completed in time, the system logs a warning message into the system event log and it is assumed that the service does not support pause/continue requests.
The common way for a Windows service to report a message is to add an entry to the system event log, which can be browsed using Event Viewer from Administrative Tools. Use methods logInfoEvent, logWarningEvent and logErrorEvent to write to the system event log informational, warning, and error messages respectively:
logErrorEvent("MySrv failed to start: MySrv.ini not found");
Each handler method, including init, is executed in a separate thread. Any exception thrown in a handler method will be ignored, so you may want to enclose bodies of your handler methods in try-blocks catching all exceptions and reporting them into the system event log:
try {
. . .
} catch (Throwable exception) {
logErrorEvent (exception.toString());
}
To build a Windows service using the JET Control Panel, do the following:
Note: The Control Panel adds the WinService API jar to the classpath automatically if you select “NT Service” as the resulting executable type. You do not need to add that jar yourself.
If you are not using the Control Panel, insert the following lines into your JET project file:
-LOOKUP=*.class=JET-directory\lib\winservice.jar
-SERVICENAME=service-name
-SERVICEMAIN=service-main-class
where
Example
-LOOKUP=*.class=C:\JET\lib\winservice.jar
-SERVICENAME=MySrv
-SERVICEMAIN=com/MyCompany/MySrv
For service testing purposes and for use with custom/third-party installation programs, JET includes a command line utility called isrv, which allows you to install and remove your service to/from the system.
The isrv syntax for service installation is as follows:
isrv -i[nstall] service-exe [ options ] [ -argsarguments ]
The following options are recognized:
| -displayname display-name | descriptive name of service |
| -auto | service will start automatically (default) |
| -manual | service will require manual startup |
| -disabled | install service in disabled state |
| -description service-desc | service description (up to 1000 chars) |
| -dependence service-name | set dependence on specified service |
| -localsystem | run under the built-in system account (default) |
| -user username | run under the account username |
| -password password | password for the specified username |
| -interactive | service may interact with desktop |
Notes:
The -args option enables you to specify the service’s command-line arguments. If -args is encountered, the rest of isrv command line is considered to be service arguments, so it must be specified after all other isrv options.
Examples
isrv -i MySrv.exe
installs the service program MySrv.exe from the current directory and specifies that it has to run automatically under the LocalSystem account, has to appear in the list of services under the system name set at compile time and cannot interact with desktop.
isrv -i C:\SRV\MySrv.exe -displayname "My Srv" -interactive
installs the service program C:\SRV\MySrv.exe and specifies that is has to run automatically under the LocalSystem account, has to appear in the list of services under the name “My Service” and is allowed to interact with desktop.
isrv -i MySrv.exe -manual -user Admin -password HaRdToGuEsS
installs the service program MySrv.exe from the current directory and specifies that it will have to be started manually by the user, will run under the Admin account, which password is HaRdToGuEsS, and has to appear in the list of services under the system name set at compile time.
Instead of specifying all parameters on the isrv command line, you may wish to use a response file:
isrv @response-file
where response-file is a name of a plain text file, any line of which either begins with a comment tag “#” or contains not more than one option setting.
Example
# MySrv.rsp -install MySrv.exe -displayname "My Service" -description "Test of the Excelsior WinService API" -localsystem -dependence MyOtherSrv -dependence MyYetAnotherSrv # Change to -auto to start the service at system boot -manual
To remove a previously installed service, issue the following command:
isrv -r[emove] service-exe
service-exe can be full or partial path to the file containing the service program. The file is not actually removed from the disk, only the respective service is unregistered.
Example
isrv -r C:\SRV\MySrv.exe
To deploy your JET-compiler service program to other computers, package it using the JetPackII deployment wizard. If you specify that you want to package a Windows service, JetPackII will prompt you for additional parameters corresponding to isrv options. See Step 8: Specifying Installation Settings Of Windows Services for details.