jogl
  1. jogl
  2. JOGL-318

ClassNotFoundException when running applet if JOGL installed into JRE

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Blocker Blocker
    • Resolution: Won't Fix
    • Affects Version/s: current
    • Fix Version/s: milestone 1
    • Component/s: jogl
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

    • Issuezilla Id:
      318

      Description

      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/issues/show_bug.cgi?id=534

        Activity

        Hide
        kcr added a comment -

        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); }
        Show
        kcr added a comment - 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); }
        Hide
        kcr added a comment -

        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); }
        Show
        kcr added a comment - 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); }
        Hide
        kbr added a comment -

        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".

        Show
        kbr added a comment - 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".
        Hide
        kcr added a comment -

        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.

        Show
        kcr added a comment - 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.
        Hide
        kbr added a comment -

        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.

        Show
        kbr added a comment - 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.

          People

          • Assignee:
            kbr
            Reporter:
            kcr
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: