Bug 318

Summary: ClassNotFoundException when running applet if JOGL installed into JRE
Product: [JogAmp] Jogl Reporter: Sven Gothel <sgothel>
Component: coreAssignee: Sven Gothel <sgothel>
Status: VERIFIED WONTFIX    
Severity: normal    
Priority: P1    
Version: 1   
Hardware: All   
OS: all   
Type: DEFECT SCM Refs:
Workaround: ---

Description Sven Gothel 2010-03-24 07:50:50 CET


---- Reported by kcr 2007-10-09 11:14:29 ----

A ClassNotFoundException is thrown when running an applet using
JNLPAppletLauncher on a system where the latest JOGL is installed into the
lib/ext directory of the JRE.

To reproduce this, copy jogl-1.1.1-rc4 into the JRE. Then run the JOGL Applet
Demo at:

https://jogl-demos.dev.java.net/applettest.html

You will get the following exception:

Exception in thread "AWT-EventQueue-2" java.lang.UnsatisfiedLinkError
	at
com.sun.gluegen.runtime.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:99)
	at com.sun.gluegen.runtime.NativeLibLoader.access$000(NativeLibLoader.java:51)
	at com.sun.gluegen.runtime.NativeLibLoader$1.run(NativeLibLoader.java:70)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.sun.gluegen.runtime.NativeLibLoader.loadGlueGenRT(NativeLibLoader.java:68)
	at
com.sun.gluegen.runtime.NativeLibrary.ensureNativeLibLoaded(NativeLibrary.java:399)
	at com.sun.gluegen.runtime.NativeLibrary.open(NativeLibrary.java:163)
	at com.sun.gluegen.runtime.NativeLibrary.open(NativeLibrary.java:129)
	at com.sun.opengl.impl.x11.DRIHack.begin(DRIHack.java:109)
	at
com.sun.opengl.impl.x11.X11GLDrawableFactory.<clinit>(X11GLDrawableFactory.java:99)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:169)
	at javax.media.opengl.GLDrawableFactory.getFactory(GLDrawableFactory.java:111)
	at javax.media.opengl.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:409)
	at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:117)
	at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:86)
	at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:79)
	at demos.applets.GearsApplet.init(GearsApplet.java:19)
	at
org.jdesktop.applet.util.JNLPAppletLauncher.startSubApplet(JNLPAppletLauncher.java:1889)
	at
org.jdesktop.applet.util.JNLPAppletLauncher.access$200(JNLPAppletLauncher.java:650)
	at org.jdesktop.applet.util.JNLPAppletLauncher$5.run(JNLPAppletLauncher.java:1261)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
	at
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Caused by: java.lang.ClassNotFoundException:
org.jdesktop.applet.util.JNLPAppletLauncher
	at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:169)
	at
com.sun.gluegen.runtime.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:85)
	... 28 more

See also Java 3D issue: https://java3d.dev.java.net/bugs/show_bug.cgi?id=534



---- Additional Comments From kcr 2007-10-09 11:15:23 ----

Evaluation:

The bug is a result of the way the ClassLoader mechanism works in Java. The
loadLibrary method in JOGL essentially does the following, as recommended by the
JNLPAppletLauncher docs:

if (usingJNLPAppletLauncher) {
  try {
    // Call JNLPAppletLauncher.loadLibrary method using reflection
  } catch (Exception e) {
    throw new UnsatisfiedLinkError...
  }
} else {
  System.loadLibrary(libraryName);
}

In the case where the JOGL classes are installed into the JRE, the
ExtensionClassLoader will load the installed JOGL classes from lib/ext, causing
them to take precedence over the JOGL classes loaded by Java Plug-in.  Because
the JOGL files are loaded by the ExtensionClassLoader and the JNLPAppletLauncher
class file is loaded by the Plug-in ClassLoader, the JOGL classes cannot see the
JNLPAppletLauncher class.

The solution is to fall back to using System.loadLibrary() if loading the
JNLPAppletLauncher class fails with a ClassNotFoundException. This is done as
follows:

boolean loaded = false;
if (usingJNLPAppletLauncher) {
  try {
    // Call JNLPAppletLauncher.loadLibrary method using reflection
    loaded = true;
  } catch (Exception e) {
    // print warning message and continue
  } catch (Exception e) {
    throw new UnsatisfiedLinkError...
  }
}

if (!loaded) {
  System.loadLibrary(libraryName);
}




---- Additional Comments From kcr 2007-10-09 11:21:54 ----

There was a typo in the suggested fix. It should be:

boolean loaded = false;
if (usingJNLPAppletLauncher) {
  try {
    // Call JNLPAppletLauncher.loadLibrary method using reflection
    loaded = true;
  } catch (ClassNotFoundException ex) {
    // print warning message and continue
  } catch (Exception e) {
    throw new UnsatisfiedLinkError...
  }
}

if (!loaded) {
  System.loadLibrary(libraryName);
}



---- Additional Comments From kbr 2007-10-10 08:15:18 ----

Putting JOGL into the JRE's lib/ext directory causes huge problems. Among other
things, it prevents us from evolving the JOGL library, because the version
dropped in to the JRE will override any version used by an application deployed
via Java Web Start or an applet.

Java 3D needs to recommend to end users not to drop the Java 3D jars into
jre/lib/ext. We're not going to support that configuration in JOGL.

Marking as "will not fix".




---- Additional Comments From kcr 2007-10-10 08:56:25 ----

Whether or not you think people should install JOGL into the JRE (and I happen
to agree that it's not the best idea), they are going to do it anyway. Refusing
to fix this bug isn't going to change that, it is instead just going to make it
harder for some people to run JOGL applets -- particularly on Apple.

In any case, the choice is: 1) fix this bug and have applets work the same way
as javaws applications; or 2) leave it broken for applets.




---- Additional Comments From kbr 2007-10-10 09:27:26 ----

People aren't going to put JOGL into the JRE's extensions directory unless
someone advises them to. For the past four years on the JOGL forum and in all of
the JOGL documentation we have advised against this practice, and we do not
support this configuration.

We're not going to put in a workaround to make this seem to work in certain
circumstances. Installing JOGL into jre/lib/ext is not a supported
configuration. If Java 3D requires JOGL to be installed there then either (a)
Java 3D needs to rethink its deployment strategy or (b) Java 3D needs to use a
private copy of JOGL utilizing a different set of namespaces than
javax.media.opengl.* and com.sun.opengl.* to avoid collisions with the mainline
releases of JOGL.




--- Bug imported by sgothel@jausoft.com 2010-03-24 07:50 EDT  ---

This bug was previously known as _bug_ 318 at https://jogl.dev.java.net/bugs/show_bug.cgi?id=318

The original assignee of this bug does not have
   an account here. Reassigning to the default assignee
   for the component, sgothel@jausoft.com.
   Previous assignee was kbr.