Index: core/src/org/netbeans/core/NbTopManager.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/NbTopManager.java,v retrieving revision 1.122 diff -u -t -r1.122 NbTopManager.java --- core/src/org/netbeans/core/NbTopManager.java 5 Oct 2001 16:01:40 -0000 1.122 +++ core/src/org/netbeans/core/NbTopManager.java 10 Oct 2001 13:59:24 -0000 @@ -755,7 +755,8 @@ public ClassLoader systemClassLoader () { ModuleSystem ms = getModuleSystem(); if (ms != null) { - return ms.getManager().getClassLoader(); + // #16265: do not go straight to ModuleManager + return ms.getSystemClassLoader(); } else { // This can be called very early: if lookup asks for ClassLoader. // For now, just give the startup classloader. Index: core/src/org/netbeans/core/modules/ModuleSystem.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/modules/ModuleSystem.java,v retrieving revision 1.10 diff -u -t -r1.10 ModuleSystem.java --- core/src/org/netbeans/core/modules/ModuleSystem.java 20 Jul 2001 18:12:50 -0000 1.10 +++ core/src/org/netbeans/core/modules/ModuleSystem.java 10 Oct 2001 13:59:25 -0000 @@ -114,31 +114,50 @@ /** Get the system classloader, for use from NbTopManager. * When it changes, NbTopManager will likewise be notified. */ - public ClassLoader getSystemClassLoader() { - if (! addedClassLoaderListener) { - addedClassLoaderListener = true; + public synchronized ClassLoader getSystemClassLoader() { + if (systemClassLoader == null) { + // First time this has been called. Set to dummy and change later. + systemClassLoader = ModuleSystem.class.getClassLoader(); + // Check for future changes. class ListenerFirer implements PropertyChangeListener, Runnable { + // do not fire too frequently: + private boolean needToChange = true; public void propertyChange(PropertyChangeEvent ev) { if (ModuleManager.PROP_CLASS_LOADER.equals(ev.getPropertyName())) { - // Exit read mutex first for safety. + // Get the new one in a write mutex. + needToChange = true; RequestProcessor.postRequest(ListenerFirer.this); } } public void run() { - NbTopManager.get().fireSystemClassLoaderChange(); - Util.err.log("fired change in system classloader"); + if (needToChange) { + needToChange = false; + // We got the change, now in write mutex get the new one. + ClassLoader nue; + mgr.mutexPrivileged().enterWriteAccess(); + try { + nue = mgr.getClassLoader(); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + synchronized (ModuleSystem.this) { + systemClassLoader = nue; + } + NbTopManager.get().fireSystemClassLoaderChange(); + Util.err.log("fired change in system classloader"); + } } } - mgr.addPropertyChangeListener(new ListenerFirer()); - } - mgr.mutexPrivileged().enterWriteAccess(); - try { - return mgr.getClassLoader(); - } finally { - mgr.mutexPrivileged().exitWriteAccess(); + ListenerFirer lf = new ListenerFirer(); + mgr.addPropertyChangeListener(lf); + // Also change ASAP to the real thing. + RequestProcessor.postRequest(lf); } + return systemClassLoader; } - private boolean addedClassLoaderListener = false; + // #16265: keep a local copy so that every call does not have to + // enter the write mutex. + private ClassLoader systemClassLoader = null; /** Produce a list of JAR files including all installed modules, * their extensions, and enabled locale variants of both.