Digital Edition

JavaNT Services
JavaNT Services

As the popularity of Java increases, many information services departments are embracing Java as the solution to their cross-platform challenges. As this trend progresses, many developers will be faced with the challenge of migrating their Java servers from UNIX to an NT boot-time environment. Administrators tend to take the attitude that since Java is a cross-platform language, this migration should be effortless. Unfortunately, this isn't the case. The thread management of child threads in the current Java Virtual Machine from Microsoft can cause problems for those developers migrating from a UNIX environment. This article explores one workaround for the thread management and garbage collection differences between the Sun and Microsoft JVMs. Microsoft recently agreed to implement a court decision to make their JVM ISO-compliant. It remains to be seen whether this will affect the behavior of Microsoft's proprietary Service class.

Considerable trial and error is associated with the migration of Java server classes to the NT environment. In the UNIX operating system it's possible simply to fork off a Java process in a script that's run at boot time. (The particular script, and the associated operating system messages that need to be caught, depends on the flavor of UNIX involved.) Under the NT operating system no fork is available, so to start a process at boot time, an NT service must be created and registered with the service's control panel. The problem inherent in this approach is that the NT OS doesn't allow fine control over the child process once it's been started. If a Java class utilizes threads, you have to override the stop method of the extended Service class to isolate and stop your threads manually. This task is made more complex because there's no definitive way to isolate your threads from the operating system threads other than their placement on the stack. Consequently, other processes started after your server may interfere with the stopping of your service. Recent versions of the Microsoft JVM have addressed this problem, but to ensure proper garbage collection, manual thread management within services is still necessary.

To create an NT service, you have to create a Java class file that extends the class provided by Microsoft in its Software Developers Kit for Java. This class is located in C:\SDK\NTService\ in version 1.02 and C:\SDK-Java.202\Bin\jntsvc\ in version 2.02 of the SDK files installed by the Microsoft SDK-Java installer. Do not attempt to unzip this file and examine the Java files. All the documentation you should need to extend the Service class is contained in the SDK-Java documents and in this article. The SDK-Java is available on Microsoft's Web site at\java\. This executable should be downloaded and installed on the system that will run the Java service. Be sure to install the Internet Explorer Java support as part of the SDK installation because the support actually installs the Java Virtual Machine. The JVM is necessary because the NT operating system won't try to access the normal Java executable located on the path; instead, it will invoke the jview executable resident within the Microsoft SDK. Microsoft's proprietary compiler and JVM contain custom hooks into the OS that are not part of the ISO standard. It remains to be seen whether these hooks will be deprecated as part of the move toward ISO compliance by Microsoft. The services control panel now defaults to the Microsoft proprietary JVM, called jview.

The Service class of the package provides methods to allow the NT OS to start, stop and pause a service. However, the JVM doesn't allow the NT services driver to access child threads of the parent class automatically. The ramifications of this are that if you create a wrapper class that extends service, you have to manually instantiate, start, pause and stop any child threads from within the wrapper class itself. Any child threads instantiated or started from within the Java class being wrappered won't be accessible from within the NT services framework. Once a child thread has been instantiated and started, the NT OS no longer knows that the child thread is grouped with its parent.

Any attempts to stop or pause a service that contains child threads without taking this into consideration will result in the OS's returning an error stating that it is unable to stop the service. To avoid this, the wrapper class in its stop method has to isolate and stop any child threads. Note that this is true for wrapper classes, while classes that directly extend the class will stop, usually without error, in version 2.02 and above. For previous versions, and to ensure proper functionality if wrappering classes are involved, manual thread grouping should still be utilized.

Listing 1 is an example of how you might extend the class to create a wrapper class that can be registered as an NT service, and will call the public static void main(String[] args) method of your Java class. To use this example code, replace YOURSERVICE with the class name of the application you wish to wrapper.

Once your Java file has been created, it needs to be compiled to bytecode. Once you have a Linking.class, move the Linking.class file to the C:\SDK-Java\NTService\ or C:\SDK-Java.202\Bin\jntsvc\ directory that was created when you ran the Microsoft SDK-Java executable. You now have a wrapper class that can be registered as an NT service.

To ensure that your target system is configured properly so you can register and use the Java service class you've created, follow the steps below.
1. Make sure there is a local (on hard drive) copy of any classes used or imported by the YOURSERVICE class; NT services aren't started in any particular order, and the networking connections may or may not be functional when the JVM attempts to start the Linking.class.
2. Place the file and the path to the tree of classes imported by YOURSELF in the CLASSPATH environmental variable in the system environment settings. (This file is located in C:\SDK\NTService\ in version 1.02 and in C:\SDK-Java. 202\Bin\jntsvc\ in version 2.02 of the SDK.) These settings can be assessed by opening the Control Panels Dialog from the Start menu and double-clicking on the System icon, which will bring up the system parameters. Clicking on the Environment Tab will access both the systemwide and the individual user parameters. You'll need to modify the system CLASSPATH parameter.

3. (If you're using version 2.02 or higher of the SDK, you can skip this step as the jntsvc registration program will modify the registry for your service.) The last step is to modify the JVM's CLASSPATH variable, because the standard Java CLASSPATH environmental variable isn't recognized by the JVM. The JVM CLASSPATH variable is explicitly defined within the JVM's set of environmental variables. Therefore it's necessary to directly modify the CLASSPATH variable that the JVM places in the system registry as follows:

  • Access the MS-DOS Command Prompt from the Start menu. In the Command Prompt window type regedit - this brings up the system registry.
  • Open the folder HKey_Local_Machine by clicking on the plus (+) sign next to the folder. Open the subfolder software and the JVM folder in the same manner. The path in the bottom left-hand corner of the System Registry Editor window should now read:

    My Computer\HKey_Local_Machine\Software \Microsoft\JavaVM

    Now open the CLASSPATH environmental variable for editing by double-clicking on the small book icon directly left of the word CLASSPATH.

  • Then remove the period at the end of the current entry and add to the current path the path to the class tree that YOURSERVICE imports. Make sure that C:\SDK-Java\NTService\ and C:\SDK-Java\NTService\ are included in the CLASSPATH. Path additions in the NT OS are separated by a ;. Remove the period at the end of the CLASSPATH before making additions, and don't add any unnecessary punctuation marks!
  • Close the System Registry Editor. The final step in the migration process is to register the service class with the NT Services Control Panel.

    Registering the Service
    For version 1.02 (this is also explained in the SDK-Java documentation):

  • In the C:\SDK-Java\NTService\i386\ directory run the svcsetup program with the command line svcsetup ServiceName Linking -classpath C:\SDK- Java\NTService\.
  • From the Start menu open the control panels, then the Services Control Panel.
  • Select the ServiceName Service and click on the STARTUP button; select automatic, and allow interaction with the desktop.
  • Select HWprofiles, and select enable.
  • Reboot your computer.

    For version 2.02:

  • In the C:\SDK-2.02\Bin\jntsvc\ directory run the jntsvc program with the command line jntsvc /out:ServiceName.exe/main:ServiceName ServiceName.class.
  • Run ServiceName.exe\install to register the Service.
  • Further documentation on use of the jntsvc should be available at C:\SDK-Java.202\Docs\SDKJDoc\def_cerv.htm provided that you installed the SDK to the default root.
  • From the Start menu open the control panels, then the Services Control Panel.
  • Select the ServiceName Service and click on the STARTUP button; select automatic, and allow interaction with the desktop.
  • Select HWprofiles, and select enable.
  • Reboot your computer.

    Testing and Evaluation
    There are two ways to see whether these procedures have been successful. The first and easiest is to open the Control Panel again and see if the service has started. If so, you've been successful. If not, an error has occurred. You can bring up the Event Viewer for the NT OS by looking under the Start menu's Administrative Tools (common) area and selecting Event Viewer.

    Set the Events to the Application log, and refresh the view. This allows you to examine the debug lines from the linking class so you can debug your classes or linking structures. Note: If the Event Viewer Application log says it can't find your class, make sure both CLASSPATH variables are set to include the paths to your linking class and all classes you wish to import.

    Many companies are pursuing Java in an attempt to reduce their operating budgets and increase their efficiency. Java is promising cross-platform compatibility. Most of the problems associated with the migration of Java can be attributed to its youth as a language. While developers feel joy about a "write once, run anywhere" ability, it's short-lived when the virtual machines don't conform to the same specifications. While Sun has made - and continues to pursue - true cross-platform compatibility among all JVMs, not all have achieved a workable level of compliance. As a result of litigation, Microsoft is migrating its JVM into compliance with the ISO standard. It remains to be seen, however, whether this migration will affect the necessarily proprietary NT Service installation classes. These differences require developers and IT staff who wish to import their code to Windows to be aware that the "write once, run anywhere" promise of Java is not always applicable in a Windows environment. Until all Java Virtual Machines behave identically, there will continue to be issues of migration for developers and IS departments to face.

    About Jim Barnabee
    Jim Barnabee is a Java architect whose main focus is designing and developing Java clients and servers for Web-based solutions to business problems. Jim has five years of Java experience (beginning with the 0.1 beta) and has been programming professionally since his junior year of high school. Jim routinely publishes online and print articles on Java development topics.

  • In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    Subscribe to the World's Most Powerful Newsletters


    "Akvelon is a software development company and we also provide consultancy services to folks who are...
    More and more brands have jumped on the IoT bandwagon. We have an excess of wearables – activity tra...
    Without lifecycle traceability and visibility across the tool chain, stakeholders from Planning-to-O...
    The Jevons Paradox suggests that when technological advances increase efficiency of a resource, it r...
    The taxi industry never saw Uber coming. Startups are a threat to incumbents like never before, and ...
    The next XaaS is CICDaaS. Why? Because CICD saves developers a huge amount of time. CD is an especia...
    One of the biggest challenges with adopting a DevOps mentality is: new applications are easily adapt...
    We are seeing a major migration of enterprises applications to the cloud. As cloud and business use ...
    HyperConvergence came to market with the objective of being simple, flexible and to help drive down ...
    Deep learning has been very successful in social sciences and specially areas where there is a lot o...
    In his session at 21st Cloud Expo, James Henry, Co-CEO/CTO of Calgary Scientific Inc., introduced yo...
    For better or worse, DevOps has gone mainstream. All doubt was removed when IBM and HP threw up thei...
    Your homes and cars can be automated and self-serviced. Why can't your storage? From simply asking q...
    Containers are rapidly finding their way into enterprise data centers, but change is difficult. How ...
    I think DevOps is now a rambunctious teenager - it's starting to get a mind of its own, wanting to g...
    "MobiDev is a software development company and we do complex, custom software development for everyb...
    The “Digital Era” is forcing us to engage with new methods to build, operate and maintain applicatio...
    Learn how to solve the problem of keeping files in sync between multiple Docker containers. In his ...
    Creating replica copies to tolerate a certain number of failures is easy, but very expensive at clou...
    "This week we're really focusing on scalability, asset preservation and how do you back up to the cl...