Once a library is loaded with System.load(), there is no way for a Java applet to unload a native Windows DLL. Customer's Windows client has acess to two web servers, each having a slightly different version of the same web service. When the client accesses this service, the server serves up a signed Java applet that runs in the user's browser. The applet checks the client disk for the presence of some native DLLs. If the DLLs are absent, or if they have the incorrect timestamp for the applet performing the check, the applet downloads the native DLLs from the server. Once the correct native DLLs are in place, the applet loads one of them using System.load(). The DLL loaded in this way then loads the other DLLs. When the applet is about to terminate, it notifies the DLL that it loaded. This DLL unloads the DLLs it loaded, using the native Windows API. The DLL loaded by the applet cannot be unloaded as there is no System.unload() call that acts as a counterpart to System.load(). This DLL remains loaded until the client browser is closed. If the client follows the above scenario to access the web service on one server, the same client is unable to then access the web service on the second server until the browser instance used for the initial access is closed. This is because the download of native DLLs from the second server fails due to the DLL loaded by the Java applet being still in use, ie not unloaded so unable to be overwritten. Downloading the native DLLs to a different directory circumvents the inability to overwrite the already loaded DLL. However, even though a System.load() is performed on the full path and name of the second DLL, it is the first DLL that is executed in JNI calls made by the applet. That is, use of a second directory does not resolve the issue; although it allows the download of the second set of native DLLs, it does not allow them to be executed by the applet. In order to allow this second download to succeed and for the DLLs thus downloaded to run, we need to force the Java applet, immediately prior to termination, to unload the native DLL that it loaded using System.load().
|