Previous articles (see Resources) have covered both creating signed applets that can access resources "outside the sandbox" and using native methods from within Java code using JNI. In this article, we're going to combine these two concepts to effectively create a Microsoft-free version of JDirect. We'll also use LiveConnect (built into Netscape Communicator) to invoke native methods directly from JavaScript.
While our example covers the Win32 API explicitly, you can easily extend the approach to run native code from an applet on any platform running the Netscape browser -- just create a different version of the native library.
Two features of Netscape's applet security model make implementing this functionality tricky. First, the native library must reside on the local drive on the client PC. While sensible, this policy requires that a DLL created using JNI be downloaded to the client.
An even trickier feature requires any class that directly invokes a native method to be loaded by the system class loader
rather than by the applet class loader. Netscape looks for classes in its own classpath first and loads classes found there
with its system class loader. If it can't find a class there, it looks in the applet's codebase. If a class is loaded from
the codebase, it gets loaded by an AppletClassLoader and thus has fewer privileges. Therefore, the class that invokes native methods must reside in Netscape's classpath by the
time it's first loaded by any applet.
In our example, we'll invoke two very simple Win32 methods called GetUserName() and GetComputerName(). GetUserName() returns the Windows user name, and GetComputerName() returns the Windows computerID. We can use this approach with any methods in the Win32 API. I've broken down our task into
the following steps:
The class file that invokes native methods needs to be downloaded to the client machine when the applet is started. This step
is just standard JNI and is well described in a number of references (see Resources). This UserInfo class doesn't need to do much -- it simply contains two native methods declarations:
public class UserInfo {
public native String getUserName() throws Error;
public native String getComputerName() throws Error;
}
To create our native interface, we need to compile UserInfo, then run the javah utility (on the Windows platform) on the generated class file to produce a C header file. This file is produced automatically
and shouldn't require any editing on your part.