Installing and Managing Operating System Services
JWService is a utility framework that allows a JWrapper application to install and manage an OS-specific service. On Windows this is a Windows service, on Mac OS a LaunchAgent or LaunchDaemon and on Linux an Upstart or Init daemon. If you are developing a cross platform application which needs to register a service, then JWService is an easy way to go about doing this.
Architecture
In order to understand how you to use JWService you must first be familiar with JWrapper's Virtual Apps. The JWService framework is utilised from two components:
- Service Virtual App: a (hidden) virtual app which you create to be installed and run as a service
- Main / Management App: your main application (or if the service is the only app you plan to create, a service management app) which can then use the JWService API to install and manage this virtual app as a service
Creating a JWService Virtual Application
Below is an example of a virtual app entry in your JWrapper configuration XML:
<App> <Name>OS Service</Name> <LogoPNG>example.png</LogoPNG> <MainClass>com.jwrapper.OSService</MainClass> <UserAccessible>false</UserAccessible> </App>
The UserAccessible element tells JWrapper that the app should not be visible to the user, and that the user should not be able to launch the virtual app. The example class com.jwrapper.OSService would be a class with a main method which contains the execution code of the service process. It should register its existence on startup via the JWService API:
public class OSService { public static void main(String [] args) { // Notify JWrapper that this service is now running JWServiceApp serviceApp = new JWServiceApp(); serviceApp.serviceStarted(); // Execute the service now. . . } }
Installing and Managing a Service
With the service virtual app created the main virtual app can call JWService to install the operating system service:
JWService.installService("OS Service", false);
The second boolean parameter above instructs JWService that this service does not require access to the window server. Once complete the service will be installed and started, and the OS Service virtual app will register itself. Call:
JWService.isServiceRunning()
to determine if the service process is currently running and
JWService.getServicePID()
to get the service process identifier. Finally, to remove the installed operating system service call
JWService.removeService()
Creating a Stop Virtual Application
JWrapper will attempt to terminate the service virtual app process when the service is removed, but on Windows it may not have sufficient permissions to do so. If you wish to gracefully stop your service then you need to create a second virtual app to terminate the service, and in there communicate with the service process and terminate it as required. Consider the following stop application which terminates the service using JWrappers JWGenericOS API:
public static void main(String [] args) { JWServiceApp app = new JWServiceApp(); int pid = app.getServicePid(); JWGenericOS.terminateProcess(pid); System.exit(0); }
You can specify the stop virtual app to use when you install the service:
JWService.installService("OS Service", "OS Stop Service", false);
JWrapper will automatically call the stop virtual app when the service is removed.
Requiring Windows Server Access
The requiresUI parameter in JWService.installService is interpretted in an OS-dependent manner. Below is a description on what effect it has on each operating system:
- Windows - the installed service is set to be INTERACTIVE. Note that this was deprecated and is no longer supported on versions of Windows later than XP and 2003.
- Mac OS - if requiresUI is true the service is installed as a LaunchAgent, else it is installed as a LaunchDaemon. Note that on OS X a LaunchAgent instance is created for each logged in user, so you should expect to have multiple instances running concurrently.
- Linux - the service process will wait for the X server to start before launching, and will negotiate appropriate XAUTHORITY permissions with which to access the server.