This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 230556 - Running with JDK1.7.0_25-b12 initializes EventQueue with the MainImpl.BootClassLoader context CL
Summary: Running with JDK1.7.0_25-b12 initializes EventQueue with the MainImpl.BootCla...
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Module System (show other bugs)
Version: 7.3
Hardware: PC Linux
: P2 normal (vote)
Assignee: Jaroslav Tulach
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-05-30 23:50 UTC by stoto79
Modified: 2013-06-22 02:08 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description stoto79 2013-05-30 23:50:13 UTC
The issue can best be seen in JDev. I've currently checked in a workaround for it, but that workaround is fragile and regresses JDev bug 14642313. So to reproduce this, first go to line 721 of OracleIdeLauncher.java and change

if (noSplash || noNag)

to

if (noSplash)

and rebuild the fcp-boot module.

This will ensure that -nonag does not initialize the event queue on the JDev side before it calls into NB. 

Also, download the JDK1.7.0_25 from http://jre.us.oracle.com/java/re/jdk/1.7.0_25/nightly/bundles/linux-x64/b12-2013-05-22_41/ into a folder, say into /scratch/foo/jdk1.7.0_25


After these preliminary steps:

1. Run ./jdev -nonag -debug --setjavahome=/scratch/foo/jdk1.7.0_25
2. See flurry of errors on startup 

The reason for that, so far as I can track it, is that the AppContext and the EventQueue have the wrong thread context classloaders. The EventDispatchThread is started with this wrong thread context classloader, too.

The cause of this seems to be that MainImpl.execute() at line 193 will call into RequestProcessor.TOP_GROUP. That will in turn call AppContext and that, in JDK1.7.0_25-b12 will also initialize the EventQueue (the latter does not happen in earlier JDK versions, as far as I can tell). 

According to Gerard Davidson "JDK-8004584: Augment applet contextualization" is probably what caused the originating JDK change. Here I am attaching Gerard's email, that may further help resolve this.

"
After working through the change in JDKu25 with Mandy and Jeff they have identified one change that might be related.

JDK-8004584: Augment applet contextualization

Unfortunately you need a specific account to access the details as this is a security bug but you can see the diffs made when resolving this issue here:

http://sa.sfbay.sun.com/projects/cpu-review_data/7u-cpu/8004584/ 
"
Comment 1 Jiri Rechtacek 2013-05-31 09:26:52 UTC
Just a note, is the problem still valid with 7u25b13? JDK-8014718 should be fixed there.
Comment 2 stoto79 2013-06-04 21:44:09 UTC
I just tried, JDK 7_25 b13 against JDEVADF_MAIN_GENERIC_130525.2345.6668 . Same issue.
Comment 3 Jaroslav Tulach 2013-06-05 14:13:44 UTC
Gerard wrote:

I have debugged this a little bit more and it appears that perhaps org.openide.util.RequestProcessor is responsible for creating a new EventQueue where as the intent appears to be to find the ThreadGroup that the root AppContext is running in:

    /**
     * @return a top level ThreadGroup. The method ensures that even Processors
     * created by internal execution will survive the end of the task.
     */
    private static final TopLevelThreadGroup TOP_GROUP = new TopLevelThreadGroup();
    private static final class TopLevelThreadGroup implements PrivilegedAction<ThreadGroup> {
        public ThreadGroup getTopLevelThreadGroup() {
            ThreadGroup orig = java.security.AccessController.doPrivileged(this);
            ThreadGroup nuova = null;

            try {
                Class<?> appContext = Class.forName("sun.awt.AppContext");
                Method instance = appContext.getMethod("getAppContext");
                Method getTG = appContext.getMethod("getThreadGroup");
                nuova = (ThreadGroup) getTG.invoke(instance.invoke(null));
            } catch (Exception exception) {
                logger().log(Level.FINE, "Cannot access sun.awt.AppContext", exception);
                return orig;
            }

            assert nuova != null;

            if (nuova != orig) {
                logger().log(Level.WARNING, "AppContext group {0} differs from originally used {1}", new Object[]{nuova, orig});
            }
            return nuova;
            
        }
        @Override
        public ThreadGroup run() {
            ThreadGroup current = Thread.currentThread().getThreadGroup();

            while (current.getParent() != null) {
                current = current.getParent();
            }

            return current;
        }
    }

This might be a change in behaviour of AppContext, if I remember rightly this used to just return the AppContext for the root ThreadGroup unless an AppContext had been specifically created for either the current ThreadGroup or an intervening parent ThreadGroup. (At least this is how it worked in JDK 6 when I last worked in this)

Instead this code causes a new AppContext to be created in the current ThreadGroup with the context class loader set to be the root NetBeans one rather than the ContextFinder loaded which is required. Could this code be simple modified to ensure that only one event queue is created at NetBeans start up?
Comment 4 Jaroslav Tulach 2013-06-06 14:03:17 UTC
Updated to JDEVADF_MAIN_GENERIC_130605.1711.6668.S, did pullsan and executed:

$ ../oracle/jdeveloper/jdev/bin/jdev -nonag --setjavahome=/scratch/jdk1.7.0_25-b15

I see no exceptions and the system runs just fine.
Comment 5 stoto79 2013-06-06 17:49:07 UTC
(In reply to comment #4)
> Updated to JDEVADF_MAIN_GENERIC_130605.1711.6668.S, did pullsan and executed:
> 
> $ ../oracle/jdeveloper/jdev/bin/jdev -nonag
> --setjavahome=/scratch/jdk1.7.0_25-b15
> 
> I see no exceptions and the system runs just fine.

It does not reproduce because there's a workaround of it in that label, currently. Please read my entire report, particularly the part:

The issue can best be seen in JDev. I've currently checked in a workaround for
it, but that workaround is fragile and regresses JDev bug 14642313. So to
reproduce this, first go to line 721 of OracleIdeLauncher.java and change

if (noSplash || noNag)

to

if (noSplash)

and rebuild the fcp-boot module.
Comment 6 stoto79 2013-06-06 21:22:28 UTC
Alterantively, get a JDEVADF label before (not including) JDEVADF_MAIN_GENERIC_130601.2354.6673. This is the first label that contains the workaround in fcp-boot.
Comment 7 Jaroslav Tulach 2013-06-07 13:33:13 UTC
I still cannot reproduce.
Comment 8 stoto79 2013-06-07 18:08:14 UTC
(In reply to comment #7)
> I still cannot reproduce.

OK, so I missed a step in my repro steps. Instead of changing the 'if' as I had iyt below, simply add

if (noNag) return;

as the first line in the showSplashScreen() method. This method was never called before my change, and the above change will have an equivalent effect. The important thing when reproducing this is that the AppContext and the EventQueue are not initialized from JDev before NB gets called.
Comment 9 Jaroslav Tulach 2013-06-08 04:56:36 UTC
OK. I see error like:

UIDefaults.getUI() failed: no ComponentUI class for: javax.swing.JComboBox[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.0,border=,flags=8,maximumSize=,minimumSize=,preferredSize=,isEditable=false,lightWeightPopupEnabled=true,maximumRowCount=8,selectedItemReminder=]                                                                                                              
java.lang.Error                                                                                                              
        at javax.swing.UIDefaults.getUIError(UIDefaults.java:731)                                                            
        at javax.swing.MultiUIDefaults.getUIError(MultiUIDefaults.java:130)                                                  
        at javax.swing.UIDefaults.getUI(UIDefaults.java:761)                                                                 
        at javax.swing.UIManager.getUI(UIManager.java:1013)                                                                  
        at javax.swing.JComboBox.updateUI(JComboBox.java:266)                                                                
        at javax.swing.JComboBox.init(JComboBox.java:231)                                                                    
        at javax.swing.JComboBox.<init>(JComboBox.java:225)                                                                  
        at oracle.ide.navigator.ApplicationNavigatorWindow.<init>

Actually I have a feeling I saw such error before - when we were doing initial steps with the windowing system - there used to be problems of this kind. CCing Standa, maybe he remembers more.
Comment 10 Jaroslav Tulach 2013-06-08 05:31:15 UTC
The UI delegate error is caused by a race condition. When

UIDefaults asks for get("ClassLoader"), it gets org.netbeans.Main$BootClassLoader and that one does not see the PLAF classes packaged as modules/bundles.

This is handled in org.netbeans.swing.plaf.Startup$CLValue. Later the module system initializes the classloader by calling:

"main"
org.netbeans.swing.plaf.Startup.setClassLoader(Startup.java:343)
org.netbeans.core.GuiRunLevel.initializeMainWindow(GuiRunLevel.java:124)
org.netbeans.core.GuiRunLevel.run(GuiRunLevel.java:98)
org.netbeans.core.startup.Main.start(Main.java:320)
org.netbeans.core.startup.TopThreadGroup.run(TopThreadGroup.java:123)
java.lang.Thread.run(Thread.java:724)

and the error is gone. When running without the -nonag, the order is somehow reversed.
Comment 11 Jaroslav Tulach 2013-06-17 07:12:36 UTC
To eliminate the UI delegate errors one needs to call

import org.netbeans.swing.plaf.Startup;
Startup.setClassLoader(Lookup.getDefault().lookup(ClassLoader.class));

"soon enough". I'll make the call sooner, but there is no guarantee the OSGi code invokes the UI creation before. To be 100% sure, the OSGi UI creation code in JDev would have to call the above itself.
Comment 12 Jaroslav Tulach 2013-06-17 07:23:59 UTC
ergonomics#66e84cf0012c
Comment 13 Quality Engineering 2013-06-22 02:08:23 UTC
Integrated into 'main-golden', will be available in build *201306212301* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/66e84cf0012c
User: Jaroslav Tulach <jtulach@netbeans.org>
Log: #230556: Register the classloader sooner