JDK-4299094 : Class Loader did not unload native library when applet closed
  • Type: Bug
  • Component: deploy
  • Sub-Component: plugin
  • Affected Version: 1.2.2
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1999-12-14
  • Updated: 2004-11-13
  • Resolved: 2000-02-02
Description
Name: rlT66838			Date: 12/13/99


Warning: JIT compiler "javacomp" not found. Will use interpreter.
java version "1.2.2"
Classic VM (build JDK-1.2.2-W, native threads, nojit)

When one or more applet use JNI to call the same shared library, the first call
in a HTML page works fine, but a second call, in the same browser session, in
another HTML page fails with the exception "UnsatisfiedLinkError: Native
Library already loaded in another classloader".

If we call each HTML page in a different browser session, it works fine.

Applets are signed with keytool.

Here is a source code that demonstrate the bug. The java source was compiled
under WinNT 4 with JDK 1.2-V, the windows native library Bug.dll with MS
VisualC++ 6.0.
The plugin used to run the applet as version 1.2.2.

--------------- Main applet class Bug.java -------------------------
package Bug;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.net.*;
import java.lang.*;

//import com.sun.java.swing.UIManager;
public class Bug extends Applet
{
  boolean isStandalone = false;
//Obtenir une valeur de param?tre

  public String getParameter(String key, String def)
  {
    return isStandalone ? System.getProperty(key, def) :
      (getParameter(key) != null ? getParameter(key) : def);
  }

  //Construire l'applet

  public Bug()
  {
  }
//Initialiser l'applet

  public void init()
  {
  }

//D?marrer l'applet

  public void start()
  {
  NativeClass nc = new NativeClass();
  int i = nc.Puiss( 2, 2);
  System.out.println( "2^2 = "+i);
  try {
      // Appel de l'URL
      URL url = new URL( getCodeBase().getProtocol(), getCodeBase().getHost(),
                            getCodeBase().getPort(), "/Bug/Bug.htm");
      System.out.println( "Calling URL "+url+" ...");
      getAppletContext().showDocument( url);
      }
  catch (Throwable ex) {
      // URL d'annulation incorrecte
      System.out.println( "*** Error : incorrect URL !");
      }
  }
//Arr?ter l'applet

  public void stop()
  {
  }
//D?truire l'applet

  public void destroy()
  {
  }
//Obtenir les informations d'applet

  public String getAppletInfo()
  {
    return "Information applet";
  }
//Obtenir les informations de param?tre

  public String[][] getParameterInfo()
  {
    return null;
  }
}
------------------ JNI class NativeClass.java ----------------------
package Bug;

public class NativeClass
{
  // return x^y
  public native int Puiss( int x, int y);
	static
	{
    try {
        System.loadLibrary("Bug");
        }
    catch( UnsatisfiedLinkError e)
        {
        System.out.println( "*** Java Exception: "+e.toString());
        }
    System.out.println( "Native Library Puiss loaded.");
	}
}
------------ Header Bug_NativeClass.h of native DLL -----------------------
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Bug_NativeClass */

#ifndef _Included_Bug_NativeClass
#define _Included_Bug_NativeClass
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Bug_NativeClass
 * Method:    Puiss
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_Bug_NativeClass_Puiss
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif
----------------- Source Bug_NativeClass.c of Native DLL ---------------------
#include "Bug_NativeClass.h"

JNIEXPORT jint JNICALL Java_Bug_NativeClass_Puiss
  (JNIEnv *jEnv, jobject jObj, jint x, jint y)
{
	jint Retour = x;
	jint i;

	if (y == 0)
		return 1;
	for (i=1; i<y; i++)
		Retour = Retour*x;
	return Retour;
}
------------------ First HTML Page called ------------------------
<html>
<head>
<title></title>
</head>
<body>
<embed type="application/x-java-applet;version=1.2.2" width="341" height="142"
align="baseline" code="Bug.Bug.class" codebase="/Bug/java"
pluginspage="/Gescas/PlugIn/JRE1_2_2-win32-i.exe" archive="Bug.jar"><NOEMBED>
<STRONG>Pas de support  du Java Development Kit version 1.2 pour les applets !!
</STRONG>
</NOEMBED>
</body>
</html>
------------------ Source of second HTML page /Bug/Bug.htm ------------
<html>
<head>
<title></title>
</head>
<body>
<p><a href="Bug2.htm">Click here to see the bug</a>...</p>
</body>
</html>
----------------- Source of third HTML page /Bug/Bug2.htm --------------
<html>
<head>
<title></title>
</head>
<body>
<embed type="application/x-java-applet;version=1.2.2" width="341" height="142"
align="baseline" code="Bug.Bug.class" codebase="/Bug/java" archive="Bug.jar">
<NOEMBED>
<STRONG>Pas de support  du Java Development Kit version 1.2 pour les applets !!
</STRONG>
</NOEMBED>
</body>
</html>
---------------------- End of source samples -----------------------

Here is the Plugin Java console output of the execution of this sample.

-------------------- Begin console output ------------------------
Java(TM) Plug-in: Version 1.2.2.px
Using JRE version 1.2.2
  User home directory = C:\WINNT\Profiles\Didier
  User has overriden browser's proxy settings.
Proxy Configuration: Manual Configuration
     Proxy:
     Proxy Overrides:
JAR cache disabled.
Opening http://pmf_dl.cessi.cnamts.fr/Bug/java/Bug.jar no proxy
CacheHandler file name: D:\WinApps\Profils
Netscape\didier_liroulet\cache\M11OTJVL.JAR
Native Library Puiss loaded.
2^2 = 4
Calling URL http://pmf_dl.cessi.cnamts.fr/Bug/Bug.htm ...
*** Java Exception: java.lang.UnsatisfiedLinkError: Native Library C:
\DRIVERS\CP8\akl5033\bin\Bug.dll already loaded in another classloader
Native Library Puiss loaded.
java.lang.UnsatisfiedLinkError: Puiss
	at Bug.Bug.start(Bug.java:44)
	at sun.applet.AppletPanel.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
--------------- End Java console output ------------------------------
(Review ID: 98791) 
======================================================================
###@###.### 2004-05-24

Comments
WORK AROUND Name: rlT66838 Date: 12/13/99 None ======================================================================
11-06-2004

EVALUATION In the current VM implementation, a native library can only be associated with one classloader. Thus, when multiple applets attempt to use the same library, the VM tries to associate the library with more than one classloader, and that's why it fails. Thus, this is a limitation of the current VM implementation, and it is not a bug. stanley.ho@Eng 2000-02-01
01-02-2000