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
When the applet is about to terminate, it notifies the DLL that it
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().