Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8017776

Swing Event Thread does not use JNLP class loader

XMLWordPrintable

    • b99
    • windows_7

        FULL PRODUCT VERSION :
        java version " 1.7.0_25 "
        Java(TM) SE Runtime Environment (build 1.7.0_25-b16)
        Java HotSpot(TM) Client VM (build 23.25-b01, mixed mode, sharing)


        ADDITIONAL OS VERSION INFORMATION :
        Have reproduced under Windows 7 64-bit Enterprise SP1; multiple user reports under XP and Vista as well; see Description below

        A DESCRIPTION OF THE PROBLEM :
        There are two ways to reproduce the problem:

        1. Launch an app under Java Web Start 10.25.2.16 from JRE 7u25 but using a Java 6 JRE (i.e. write the JNLP file so that it prefers a Java 6 JRE and ensure one is available in the Java control panel)

        2. Run under 7u25 alone with the Java console disabled - I am unable to reproduce this myself but we have done so within our organisation and many users report this issue with only 7u25 installed. For affected users, the problem is always reproducible; I have been unable to determine why this only happens to some users and not others. Enabling the Java console in control panel advanced settings makes the issue go away for all users.

        In either case, the EDT will use the JRE default classloader as its context class loader. This causes a number of issues including loading custom look and feel by name, using RMI stub classes and others. The test case below triggers the bug by loading a custom Swing LaF.

        REGRESSION. Last worked in version 7u25

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Run an application under Java Web Start and set a custom look and feel (not one provided by the JRE, but one loaded via the JNLP classloader)

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The custom LaF should be installed and used. This is what happens when running under Java Web Start from JRE 7u21 or earlier, or when running outside of Web Start.

        When running under JWS from 7u21 or earlier outputting the EDT context classloader shows it is using the JNLP classloader:

        Classloader: com.sun.jnlp.JNLPClassLoader@1193779

        ACTUAL -
        The event thread is not using the Java Web Start class loader and fails to load the custom LaF class

        Classloader: sun.misc.Launcher$AppClassLoader@affc70
        java.lang.ClassNotFoundException: com.piperoglou.webstartlaftest.WebStartLookAndFeelTestHarness$MyLookAndFeel
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:249)
        at javax.swing.SwingUtilities.loadSystemClass(SwingUtilities.java:1850)
        at javax.swing.UIManager.setLookAndFeel(UIManager.java:557)
        at com.piperoglou.webstartlaftest.WebStartLookAndFeelTestHarness$1.run(WebStartLookAndFeelTestHarness.java:22)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:672)
        at java.awt.EventQueue.access$400(EventQueue.java:81)
        at java.awt.EventQueue$2.run(EventQueue.java:633)
        at java.awt.EventQueue$2.run(EventQueue.java:631)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:642)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)


        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        java.lang.ClassNotFoundException: com.piperoglou.webstartlaftest.WebStartLookAndFeelTestHarness$MyLookAndFeel

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        package com.piperoglou.webstartlaftest;

        import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
        import java.awt.BorderLayout;
        import java.awt.Container;
        import javax.swing.JFrame;
        import javax.swing.JTextArea;
        import javax.swing.SwingUtilities;
        import javax.swing.UIManager;
        import javax.swing.WindowConstants;

        public class WebStartLookAndFeelTestHarness {

            public static void main(String[] args) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            System.out.println( " Classloader: " + Thread.currentThread().getContextClassLoader());
                            UIManager.setLookAndFeel( " com.piperoglou.webstartlaftest.WebStartLookAndFeelTestHarness$MyLookAndFeel " );
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        JTextArea textArea = new JTextArea( " The quick brown fox jumped over the lazy dog. How rude. " , 50, 10);
                        textArea.setLineWrap(true);
                        textArea.setWrapStyleWord(true);

                        JFrame frame = new JFrame( " Java Web Start Look & Feel Test " );
                        frame.setBounds(50, 50, 200, 200);
                        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

                        Container contentPane = frame.getContentPane();
                        contentPane.setLayout(new BorderLayout());
                        contentPane.add(textArea, BorderLayout.CENTER);

                        frame.setVisible(true);
                    }
                });
            }

            public static class MyLookAndFeel extends WindowsLookAndFeel {
                private static final long serialVersionUID = -7686127811595151510L;
            }

        }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        - For users that have Java 7u25 installed only, enable the Java Console
        - For users that use Java Web Start from Java 7u25 but are using an older JRE, disable the older JRE and the Java Console

        Also, in code (Credit for this to Oracle forum user theskad81 from https://forums.oracle.com/thread/2552214 with small changes by myself)

        private static void quickAndDirtyFixForProblemWithWebStartInJava7u25() {
                if (! " javaws-10.25.2.16 " .equals(System.getProperty( " javawebstart.version " ))) {
                    return;
                }
                LOGGER.info( " Java Web Start 10.25.2.16 (from JRE 7u25) detected - applying classloader fix " );

                final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                try {
                    SwingUtilities.invokeAndWait(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                // Change context in all future threads
                                final Field field = EventQueue.class.getDeclaredField( " classLoader " );
                                field.setAccessible(true);
                                final EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
                                field.set(eventQueue, classLoader);
                                // Change context in this thread
                                Thread.currentThread().setContextClassLoader(classLoader);
                            } catch (Exception e) {
                                LOGGER.error( " Unable to apply 'fix' for java 1.7u25 " , e);
                            }
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

              dmarkov Dmitry Markov
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              12 Start watching this issue

                Created:
                Updated:
                Resolved: