HOWTO: Compile Java applications to NT services
Article ID: 000019 PDF Version: 000019.pdf The information in this article applies to:
All mentioned examples for this article may be found here. A Windows service, also 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/2003 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 marked for automatic startup (i.e. to be launched at system bootstrap) or manual startup (to be activated by another service or by a user through Control Panel/Services). Excelsior JET eases conversion of programs written in the Java programming language into Windows services through providing the Excelsior WinService API and supporting it in the compiler and runtime. The API has one base class WinService with special methods called control handlers. To convert your Java application to a Windows service, you must extend the WinService class with your own and implement one or more control handler methods in it. For instance, when the user selects your service in the Control Panel/Services applet and clicks the Pause button, the pause() method of your WinService subclass is called. You should implement it to provide the pause functionality. 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 only have to override the WinService.run() method, implementing the main functionality of your service. Suppose you have a simple Java program which you want to convert to an NT Service:
First, make the HelloWorld class extending com.excelsior.service.WinService class. Then, services have no single entry point such as the main method in conventional Java applications. Instead, they must implement control handler methods of the base class WinService. The main body of the service should be placed in the run handler. Note, that the instance of the HelloWorld class is created implicitly by the JET runtime during the service startup. So ensure that the default constructor is declared in the service class, and has the public access modifier. Finally, services do not have a console or standard output stream. The common way for a Windows service to issue a message is to add an entry to the system event log, which can be browsed using Event Viewer from Administrative Tools. So it is necessary to replace the System.out.println() call with a call of WinService.logInfoEvent().
This service simply adds an informational event with the text "Hello, world!" to the system event log every hour. For more information about writing to the system event log, see Excelsior JET for Windows User’s Guide (Chapter “Windows NT services”, Sections “Windows services overview” and “Excelsior WinService API”). IMPORTANT: the run() method implements the main service functionality. Upon return from that method, the service stops. So the run() method is very similar to a conventional Java program’s main() method, with one major distinction:
If you wish your service program to wait for a proper exit of other threads, you should implement that programmatically in the run() method. You may separate service initialization from its main functionality by moving initialization code to the init() method, which is invoked before the run() method when the service is started. The service reports to the system that it is up and running by completing the init() method. The init() method returns a boolean indicating whether the service accepts pause/resume control requests. If the init() method has completed in time (see below), the run() method is invoked immediately.
To allow the user to control the service, implement the respective control methods (if your service supports pause/resume requests, make sure that the init() handler returns true.)
Note: 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 WinService method, e.g. setInitTimeout(). The timeout for the shutdown() handler is defined by the system (as less than 20 seconds) and cannot be adjusted. If the method init() has not completed in time, the system logs a warning message into the system event log and assumes that the service does not support pause/continue requests.
To build a Windows service program using the JET Control Panel, do the following:
For service testing purposes and for use with custom/third-party installation programs, Excelsior JET includes a command line utility called isrv, which allows you to install and remove your service to/from the system. For example, to install the HelloWorld service you have just built, go to the build directory and issue the following command: isrv -i HelloWorld.exe -displayname "HelloWorld Service" The above command installs the service program HelloWorld.exe from the current directory and specifies that it has to appear in the list of services under the name "HelloWorld Service". Other isrv options have been left to defaults, which are as follows:
To remove the previously installed service, issue the following command: isrv -r HelloWorld.exe For more isrv options and examples, please refer to Excelsior JET for Windows User’s Guide (Chapter “Windows NT Services”, Section “Service installation and removal”). To create an installation package for your service, run JetPackII from your Excelsior JET Start Menu and do the following:
Hint: A service starts up with the current directory set to the Windows 32-bit system directory, regardless of where the service executable resides. If your service needs to know its installation directory (e.g. for reading/writing files), you have two options:
Copyright © 2003-2006 Excelsior LLC. All rights reserved.
|
|
Home | Company | Products | Services | Resources | Blog | Contact | Request a Call Site: Search | Sitemap | Forum | Credits © 1999-2006 Excelsior LLC. All Rights Reserved. |