Extending Your NLM System into Java, with Ease
Articles and Tips: article
Senior Research Engineer
01 Jan 1998
The first of a series of articles on applying Novell technologies towards a network- centric computing model; aimed at those who have an existing client/server application that uses NLMs to implement the service side. Discusses Java speed issues and what is being done about them. Describes a Java/NLM gateway to enable Java applets to access the service routines in existing NLMs.
This is the first article in our ongoing series on applying Novell technologies towards a network-centric computing model. This article is specifically aimed at those of you who may have an existing client/server application that uses NLMs to implement the service side.
Because of the industry direction towards a network-centric computing model (see the article titled "Quo Vadis" in the December 1997 issue), you may have thought about moving your application to Java to take advantage of its platform independence, open standards, accessability, ease of programming, extensibility, its present and/or future functionality, and so on.
However, to be honest, we could think of three reasons why you might be reluctant to do this immediately:
1. You don't have the time and/or resources to rewrite all of your application's code in Java.
2. You have a large installed base and don't want to inconvenience your users with an upgrade.
3. Even if you were to rewrite your app's code and upgrade your client base, you feel that Java's speed might be unacceptable on the server side.
The section found later in this article will describe a Java/NLM gateway to enable Java applets to access the service routines in existing NLMs. Also in this issue, you will find an article that discusses this system at the Java source-code level. In the next issue, you will find an article that discusses the NLM side at a C source-code level.
Using a Java/NLM gateway, you can extend your current client base to include applets running in Java-enabled browsers on machines without the Novell client installed, including non-Wintel machines like the Mac. The best part is that you may not have to alter the code in your existing C-based NLM or C-based client at all.
But before we get into the coding details for the Java/NLM gateway, let's get an update on what is being done about Java speed issues.
Java Speed Issues
Because of its dynamic interpretive nature, Java will probably never have the same performance as compiled C code. However, Sun, Novell, and the Java community are working to improve this situation and have come up with some solutions.
Java is currently perceived to have three main speed issues:
1. Method invocation and object instantiation
2. Garbage collection
3. Thread synchronization
Speed Issue: Method Invocation and Object Instantiation
One of the differences between Java and a staticly compiled procedural language like C is that, in C, the location of a called function is resolved at compile time in the form of an absolute offset value. This simple reference works for a static environment like C but is not adequate for an object-oriented language with a dynamic runtime environment like Java.
When a method is called in Java, nothing may be known about it except its fully qualified name. To access a method, Java may need to resolve the name to locate and load related classes, instantiate objects, run constructors, and then locate a method with the proper signature in the appropriate class in the loaded hierarchy.
As you can imagine, invoking a method in a dynamic object-oriented environment like Java can be expensive. Method invocation can especially impact performance if the application has a finely grained design with a large number of little methods each having this method invocation overhead when called.
Solution: JITs and Heuristic Compiler
Just In Time (JIT) compilers are available today from Sun which increase the speed of Java executables by up to 50 times on Solaris platforms. A JIT accomplishes this speed increase by compiling all of a class's byte code to native machine code when it is loaded. The result is that the name resolution task data for all of the method invocations in the byte code is developed once and then cached. Because this inital translation task takes time, long-running, processor-intensive programs which reuse the same classes over and over again derive the most benefit from JIT technology.
In addition, Novell and others are currently working on a new approach, a heuristic compiler. The idea behind a heuristic compiler is that as the program is being used, the heuristic compiler uses various adaptive algorithms to identify the most commonly used paths through the program's byte code. Then unlike a normal JIT, which compiles all of the byte code for each class as it is loaded, a heuristic compiler will compile only those paths which are most commonly used. The result is that class loading time is significantly less than with a JIT compiler while retaining most of the compiled code reuse benefit that would be supplied by a JIT.
With the heuristic compiler, speed improvements could result in Java applications running on Novell platforms at performance levels comparable to C++ executables.
Speed Issue: Garbage Collection
Java's garbage collection thread is automatically run periodically and on an as-needed basis (it may also be called directly with the static System.gc( ) method). During garbage collection, the finalizer methods for all out of scope objects with no references to them are run and then the objects are deleted from the Java runtime heap. The process of determining whether or not a reference exists to an object, managing the finalizer que, and running finalizer methods takes some time. In fact, some developers have complained of multi-second pauses in their Java executables when garbage collection occurs, especially when working with large amounts of data.
Solution: Use a Smaller Runtime Heap If Possible
Surprisingly, the experts say that the Java VM's garbage collection is already pretty efficient. Profiles of the Java Web Server show it spending less than two percent of its time running the garbage collection thread. However, the larger the specified runtime heap, the less often the garbage collection thread is run and the longer it can take when it is given time. This results in the perception that garbage collection is very expensive.
Regardless of how efficient Java garbage collection is already, it is being improved upon. Sun is developing technologies like a "fully generational copying collector with scavenging for short-lived objects" and "non-disruptive incremental collection of long-lived objects." I won't even begin to explain what this means. Hopefully, it is enough to say that garbage collection will get better or even better depending on your perspective.
Speed Issue: Thread Synchronization
Synchronized method invocation takes about six times longer than non-synchronized method invocation.
Solution: New Byte-Code Intrepreters
Sun's next-generation Virtual Machine will implement a new thread- synchronization technology which will make synchronization on objects where there is no contention for the lock, practically free.
More Speedy Solutions: Tips and Tricks
There are many tips and tricks that can dramatically improve your Java code's performance. You can find many of these suggestions and a whole lot of other information described at Web sites like the Java Developer Connection at http://developer.javasoft.com/developer/index.html. Incidently, in the case of the JDC, membership is free.
Introducing the Java/NLM Gateway Example
The rest of this article will provide a high-level description of a Java/NLM gateway that can be used to enable Java applets to access service routines in NLMs.
As we said earlier, by using a Java native method, you can extend your current client base to include applets running in Java-enabled browsers on machines without the Novell client installed. Maybe the best part of this scheme is that you may not have to alter the code in your NLMs or client at all to extend your existing NLM-based application into the Java world. A buildable sample project (including Java and C sources) will be available at the download site shown at the end of this article.
To facilitate our discussion, this article will describe the development of a Java/NLM gateway for a real client/server application called API_Info using the block diagram in Figure 1. API_Info is a C-based, NDS-enabled application that has been fully described in a series titled "The Anatomy of a Simple IntranetWare Client/Server Application" in the September, October, and November 1997 issues.
Figure 1:API_Info Application with Java/NLM gateway.
The version of the API_Info Applet client described in this issue will not use NDS to find the optimal instance of an API_Info NLM instance on the network as does the C-based version of the API_Info client. In a later issue, we will extend the applet client to use JNDI to perfom the NDS functionality available in the C-based client.
Java/NLM Gateway Block Diagram Explanation
A high level block diagram for this issue's version of API_Info with both the Applet and original C-based clients is shown in Figure 1.
The core network functionality for the C-based client is located in the IntranetWare client DLLs (not shown), installed on the client machine. The API_Info.DLL makes standard IntranetWare calls to the IntranetWare client DLLs to connect to the server running the NLM. The IntranetWare client DLLs must be installed on the client machine for the C-based client to work. Once a connection to the NLM is built, the API_Info.DLL uses an NCP extension to transact with the service NLM over the connection.
On the Java side, the client's core network functionality is located in the standard Java classes installed with the browser. These include URL, URLConnection, Socket, and more. The API_Info applet-specific classes reside along with the HTML document that references them on the Web server. The HTML document is loaded across a connection built by the browser when the user enters the appropriate URL into the browser. The HTML in the document tells the browser to load the main API_Info applet class. Loading the API_Info applet class causes the rest of the API_Info applet classes to be loaded as well.
Once loaded into the browser's Java Virtual Machine (JVM), the classes constituting the API_Info applet client attempt to obtain a socket connection to an API_Info Java application running on the Web server's JVM. The sole purpose of this application is to listen for client applet connections and spawn a thread for each one that it receives.
Each client thread spawned by the application, reads the client's request to the server over the client's socket connection and passes it to the native method in the API_Info GateWay NLM. The purpose of the API_Info GateWay NLM is to serve as the translator between the Java world and the NLM world.
The API_Info Java application and the API_Info GateWay NLM use the Java Native Method Interface to accomplish the binding necessary to extend the native functionality of the Java Virtual Machine to include the API_Info service.
Note: Two companion articles contain code-level descriptions of the API-Info Java/NLM system; they also explain JNI and tell how to use it.
"The Java Side of the API_Info Java/NLM Gateway Example" (this issue)
"The NLM Side of the API_Info Java/NLM Gateway Example" (next issue)
The Java Native Interface package or JNI is part of Java version 1.1, so the Web Server must be Java 1.1 enabled for this application to run. You can download your IntranetWare/Java SDK which includes the Java 1.1 NLM for your Web server from http://developer.novell.com/java/sdk.
On the NLM side, the API_Info gateway NLM has been built with a directive to import the Service NLM's service routine while the API_Info NLM has been built with a directive to export its service routine. This implied contract is necessary for the gatway NLM to access the service routine in the Service NLM.
When the gateway NLM's routine is called, control is passed to the routine on the thread spawned for the client by the Java application in the JVM. The gateway routine simply passes the request directly to the Service NLM's service routine.
Still on the client thread spawned by the Java application, the API_Info service routine services the request and returns a response buffer to the gateway which returns it to the application. Still on the client thread spawned by the Java application, the native method returns the response buffer to the client applet making the request. The response buffer is sent back to the client applet over the client's connection and the thread is terminated.
This article has described some speed issues with Java and some of the things being done about them. It has also provided a high-level description of a Java/NLM gateway that can be used to enable Java applets to access service routines in NLMs thereby providing a system with the server side speed of an NLM and the flexibility of clients in a Web browser.
For code level descriptions of the API_Info Java/NLM Gateway system refer to the following two articles:
"The Java Side of the API_Info Java/NLM Gateway Example" (this issue)
"The NLM Side of the API_Info Java/NLM Gateway Example" (next issue)
Things to Come
In a later issue, we will extend the applet client to use JNDI to perfom the NDS functionality available in the C-based client. This will be followed by an article describing how to add functionality to an applet client enabling it to use LDAP to access NDS from outside of the firewall.
Also at a later date, we will provide you with a Windows NT version of the API_Info service via our download site on the Web. This service can then be installed on NT servers running NDS. Because Java is cross-platform, the same applet client described above could then be used to access an instance of the API_Info service running on an NT server or one running on IntranetWare.
Our Download Site
You can use the URL shown below to access our download site for all sources found in subsequent issues of this publication including the sources for the C-based API_Info application and the API_Info Java/NLM gateway system.
The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.