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.

View | Details | Raw Unified | Return to bug 30971
Collapse All | Expand All

(-)manifest.mf (+14 lines)
Lines 7-10 Link Here
7
OpenIDE-Module-Localizing-Bundle: org/netbeans/core/Bundle.properties
7
OpenIDE-Module-Localizing-Bundle: org/netbeans/core/Bundle.properties
8
OpenIDE-Module-Layer: org/netbeans/core/resources/mf-layer.xml
8
OpenIDE-Module-Layer: org/netbeans/core/resources/mf-layer.xml
9
OpenIDE-Module-Provides: org.openide.modules.InstalledFileLocator
9
OpenIDE-Module-Provides: org.openide.modules.InstalledFileLocator
10
Covered-Packages: org.netbeans.beaninfo,org.netbeans.beaninfo.editors,
11
 org.netbeans.beaninfo.editors.resources,org.netbeans.core,
12
 org.netbeans.core.actions,org.netbeans.core.awt,
13
 org.netbeans.core.filesystems,
14
 org.netbeans.core.modules,org.netbeans.core.perftool,
15
 org.netbeans.core.projects,org.netbeans.core.projects.cache,
16
 org.netbeans.core.resources,org.netbeans.core.resources.actions,
17
 org.netbeans.core.resources.frames,org.netbeans.core.resources.welcome,
18
 org.netbeans.core.resources.windowmanager,org.netbeans.core.ui,
19
 org.netbeans.core.windows,org.netbeans.core.windows.dnd,
20
 org.netbeans.core.windows.frames,org.netbeans.core.windows.layers,
21
 org.netbeans.core.windows.nodes,org.netbeans.core.windows.toolbars,
22
 org.netbeans.core.windows.util,org.netbeans.core.xml,
23
 META-INF,META-INF.services
10
24
(-)bootstrap/src/org/netbeans/JarClassLoader.java (-6 / +55 lines)
Lines 26-31 Link Here
26
import java.util.*;
26
import java.util.*;
27
import java.lang.reflect.Field;
27
import java.lang.reflect.Field;
28
import java.lang.reflect.Modifier;
28
import java.lang.reflect.Modifier;
29
import java.util.jar.JarEntry;
29
30
30
/**
31
/**
31
 * A ProxyClassLoader capable of loading classes from a set of jar files
32
 * A ProxyClassLoader capable of loading classes from a set of jar files
Lines 43-49 Link Here
43
    /** Creates new JarClassLoader.
44
    /** Creates new JarClassLoader.
44
     * Gives transitive flag as true.
45
     * Gives transitive flag as true.
45
     */
46
     */
46
    public JarClassLoader (List files, ClassLoader[] parents) {
47
    public JarClassLoader (List files, ProxyClassLoader[] parents) {
47
        this(files, parents, true);
48
        this(files, parents, true);
48
    }
49
    }
49
    
50
    
Lines 51-58 Link Here
51
     * @since org.netbeans.core/1 > 1.6
52
     * @since org.netbeans.core/1 > 1.6
52
     * @see ProxyClassLoader#ProxyClassLoader(ClassLoader[],boolean)
53
     * @see ProxyClassLoader#ProxyClassLoader(ClassLoader[],boolean)
53
     */
54
     */
54
    public JarClassLoader(List files, ClassLoader[] parents, boolean transitive) {
55
    public JarClassLoader(List files, ProxyClassLoader[] parents, boolean transitive) {
55
        super(parents, transitive);
56
        super(parents, getCoveredPackages(files), transitive);
56
57
57
        sources = new Source[files.size()];
58
        sources = new Source[files.size()];
58
        try {
59
        try {
Lines 109-115 Link Here
109
        return val;
110
        return val;
110
    }
111
    }
111
112
112
    protected Class simpleFindClass(String name, String path, String pkgnameSlashes) {
113
    protected Class doLoadClass(String name) {
114
//    protected Class simpleFindClass(String name, String path, String pkgnameSlashes) {
115
        String path = name.replace('.', '/').concat(".class"); // NOI18N
116
113
        // look up the Sources and return a class based on their content
117
        // look up the Sources and return a class based on their content
114
        for( int i=0; i<sources.length; i++ ) {
118
        for( int i=0; i<sources.length; i++ ) {
115
            Source src = sources[i];
119
            Source src = sources[i];
Lines 128-134 Link Here
128
            // to have the same Package object, proper sealing check, etc.; so be safe,
132
            // to have the same Package object, proper sealing check, etc.; so be safe,
129
            // overhead is probably small (check in parents, nope, check super which
133
            // overhead is probably small (check in parents, nope, check super which
130
            // delegates to system loaders).
134
            // delegates to system loaders).
131
            Package pkg = getPackageFast(pkgName, pkgnameSlashes, isSpecialResource(pkgnameSlashes));
135
            Package pkg = getPackageFast(pkgName, true);
132
            if (pkg != null) {
136
            if (pkg != null) {
133
                // XXX full sealing check, URLClassLoader does something more
137
                // XXX full sealing check, URLClassLoader does something more
134
                if (pkg.isSealed() && !pkg.isSealed(src.getURL())) throw new SecurityException("sealing violation"); // NOI18N
138
                if (pkg.isSealed() && !pkg.isSealed(src.getURL())) throw new SecurityException("sealing violation"); // NOI18N
Lines 141-146 Link Here
141
        } 
145
        } 
142
        return null;
146
        return null;
143
    }
147
    }
148
    
144
    // look up the jars and return a resource based on a content of jars
149
    // look up the jars and return a resource based on a content of jars
145
    protected URL findResource(String name) {
150
    protected URL findResource(String name) {
146
        for( int i=0; i<sources.length; i++ ) {
151
        for( int i=0; i<sources.length; i++ ) {
Lines 228-234 Link Here
228
     * Should help reloading modules with changed resources.
233
     * Should help reloading modules with changed resources.
229
     */
234
     */
230
    public void destroy() {
235
    public void destroy() {
231
        super.destroy();
236
//        super.destroy();
232
        for (int i = 0; i < sources.length; i++) {
237
        for (int i = 0; i < sources.length; i++) {
233
            if (sources[i] instanceof JarSource) {
238
            if (sources[i] instanceof JarSource) {
234
                JarFile j = ((JarSource)sources[i]).getJarFile();
239
                JarFile j = ((JarSource)sources[i]).getJarFile();
Lines 445-449 Link Here
445
    
450
    
446
    static void notify (int x, Throwable t) {
451
    static void notify (int x, Throwable t) {
447
        t.printStackTrace();
452
        t.printStackTrace();
453
    }
454
    
455
static long sum = 0;
456
457
    private static Iterator getCoveredPackages(List files) {
458
long time = System.currentTimeMillis();
459
        Set known = new HashSet();
460
        for (Iterator it = files.iterator(); it.hasNext();) {
461
            JarFile act = (JarFile)it.next();
462
	    Manifest m = null;
463
	    try {
464
	        m = act.getManifest();
465
	    } catch (IOException io) {
466
io.printStackTrace();
467
	    }
468
	    if (m != null) {
469
		Attributes attr = m.getMainAttributes();
470
		String pack = attr.getValue("Covered-Packages");
471
		if (pack != null) {
472
//System.err.println("pack=" + pack);
473
		    Enumeration en = new StringTokenizer(pack,",");
474
		    while (en.hasMoreElements()) {
475
			String str = (String)en.nextElement();
476
//System.err.println("Adding package '" + str + "'");
477
			known.add(str);
478
		    }
479
		    continue;
480
		}
481
	    }
482
            Enumeration en = act.entries();
483
            while (en.hasMoreElements()) {
484
                JarEntry je = (JarEntry)en.nextElement();
485
                if (! je.isDirectory()) {
486
                    String itm = je.getName();
487
                    int slash=itm.lastIndexOf('/');
488
                    String pkg = itm.substring(0, slash).replace('/','.');
489
                    known.add(pkg);
490
                }
491
            }
492
        }
493
time = System.currentTimeMillis()-time;
494
sum += time;
495
System.err.println("Scanned packages took " + time + "ms, total=" + sum + "ms");
496
        return known.iterator();
448
    }
497
    }
449
}
498
}
(-)bootstrap/src/org/netbeans/Main.java (-4 / +6 lines)
Lines 76-84 Link Here
76
        }
76
        }
77
        
77
        
78
        // XXX separate openide.jar and core*.jar into different classloaders
78
        // XXX separate openide.jar and core*.jar into different classloaders
79
        ClassLoader loader = new BootClassLoader(list, new ClassLoader[] {
79
        ClassLoader loader = new BootClassLoader(list, new ProxyClassLoader[0]
80
            Main.class.getClassLoader()
80
// {
81
        });
81
//            Main.class.getClassLoader()
82
//        }
83
); 
82
        
84
        
83
        String className = System.getProperty(
85
        String className = System.getProperty(
84
            "netbeans.mainclass", "org.netbeans.core.Main" // NOI18N
86
            "netbeans.mainclass", "org.netbeans.core.Main" // NOI18N
Lines 119-125 Link Here
119
    }
121
    }
120
    
122
    
121
    private static final class BootClassLoader extends JarClassLoader {
123
    private static final class BootClassLoader extends JarClassLoader {
122
        public BootClassLoader(List cp, ClassLoader[] parents) {
124
        public BootClassLoader(List cp, ProxyClassLoader[] parents) {
123
            super(cp, parents);
125
            super(cp, parents);
124
        }
126
        }
125
        /** Startup optimalization. See issue 27226. */
127
        /** Startup optimalization. See issue 27226. */
(-)bootstrap/src/org/netbeans/ProxyClassLoader.java (-320 / +146 lines)
Lines 7-13 Link Here
7
 * http://www.sun.com/
7
 * http://www.sun.com/
8
 * 
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun
11
 * Microsystems, Inc. All Rights Reserved.
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
12
 */
13
13
Lines 20-105 Link Here
20
import java.security.PrivilegedAction;
20
import java.security.PrivilegedAction;
21
21
22
/**
22
/**
23
 * A class loader that has multiple parents and uses them for loading
23
 * A special class loader optimized for working in the enviroment
24
 * classes and resources. It can be used in tree hierarchy, where it
24
 * of a deeply nested classloader hierarchy. It uses shared knowledge
25
 * can exploit its capability to not throw ClassNotFoundException when
25
 * about package population to direct the loading request directly
26
 * communicating with other ProxyClassLoader.
26
 * to the correct classloader.
27
 * It itself doesn't load classes or resources, but allows subclasses
28
 * to add such functionality.
29
 *
27
 *
30
 * @author  Petr Nejedly, Jesse Glick
28
 * @author  Petr Nejedly
31
 */
29
 */
32
public class ProxyClassLoader extends ClassLoader {
30
public class ProxyClassLoader extends ClassLoader {
33
    /** empty enumeration */
31
//XXX - add destroy() which will clean system-wide mapping cache
34
    private static final Enumeration EMPTY = new ArrayEnumeration (new Object[0]);
35
    
32
    
36
    /**
33
    private static ClassLoader systemCL = ClassLoader.getSystemClassLoader();
37
     * All known package owners.
38
     * Packages are given in format <samp>org/netbeans/modules/foo/</samp>.
39
     * Of type <code>Map&lt;String,ClassLoader&gt;</code>.
40
     */
41
    private final Map domainsByPackage = new HashMap(); 
42
    /** All known packages, of type <code>Map&lt;String,Package&gt;</code> */
43
    private final Map packages = new HashMap();
44
45
    /** All parents of this classloader, including their parents recursively */
46
    private ClassLoader[] parents;
47
48
    /** if true, we have been destroyed */
49
    private boolean dead = false;
50
    
51
    private final boolean transitive;
52
    
53
    /** Create a multi-parented classloader.
54
     * Loads recursively from parents.
55
     * @param parents list of parent classloaders. 
56
     * @throws IllegalArgumentException if there are any nulls or duplicate
57
     * parent loaders or cycles.
58
     */
59
    public ProxyClassLoader( ClassLoader[] parents ) {
60
        this(parents, true);
61
    }
62
    
63
    /** Create a multi-parented classloader.
64
     * @param parents list of parent classloaders. 
65
     * @param transitive whether other PCLs depending on this one will
66
     *                   automatically search through its parent list
67
     * @throws IllegalArgumentException if there are any nulls or duplicate
68
     * parent loaders or cycles.
69
     * @since org.netbeans.core/1 > 1.6
70
     */
71
    public ProxyClassLoader(ClassLoader[] parents, boolean transitive) {
72
        if (parents.length == 0) {
73
            throw new IllegalArgumentException ("ProxyClassLoader must have a parent"); // NOI18N
74
        }
75
        
76
        this.transitive = transitive;
77
        
78
        Set check = new HashSet(Arrays.asList(parents)); // Set<ClassLoader>
79
        if (check.size() < parents.length) throw new IllegalArgumentException("duplicate parents"); // NOI18N
80
        if (check.contains(null)) throw new IllegalArgumentException("null parent in " + check); // NOI18N
81
34
82
        this.parents = coalesceParents(parents);
35
    /** A Map<String,Set<ClassLoader>> of all packages known by all classloaders */
36
    private static Map packageCoverage = new HashMap();
37
    
38
    private boolean transitive;
39
    private Set parentSet = new HashSet();
40
    private ProxyClassLoader[] parents;
41
    private Map packages = new HashMap();
42
    
43
    private static Map sclPackages = new HashMap(); 
44
    
45
    /**
46
     * @param parents all direct parents of this classloader, except system one.
47
     * @param coveredPackages Enumeration of Strings if format "org.something"
48
     *   containing all packages to be covered by this classloader.
49
     */
50
    public ProxyClassLoader(ProxyClassLoader[] parents, Iterator coveredPackages, boolean transitive) {
51
	this.transitive = transitive;
52
	
53
	this.parents = coalesceParents(parents);
54
	parentSet.addAll(Arrays.asList(this.parents));
55
//System.err.println("Covered packages:");    
56
	while (coveredPackages.hasNext()) {
57
	    String pkg = (String)coveredPackages.next();
58
//System.err.println("  '" + pkg  +"'");
59
	    Set delegates = (Set)packageCoverage.get(pkg);
60
	    if (delegates == null) {
61
		delegates = new HashSet();
62
		packageCoverage.put(pkg, delegates);
63
	    }
64
	    delegates.add(this);
65
	}
83
    }
66
    }
84
    
67
    
85
    // this is used only by system classloader, maybe we can redesign it a bit
68
        // this is used only by system classloader, maybe we can redesign it a bit
86
    // to live without this functionality, then destroy may also go away
69
    // to live without this functionality, then destroy may also go away
87
    /** Add new parents dynamically.
70
    /** Add new parents dynamically.
88
     * @param parents the new parents to add (append to list)
71
     * @param parents the new parents to add (append to list)
89
     * @throws IllegalArgumentException in case of a null or cyclic parent (duplicate OK)
72
     * @throws IllegalArgumentException in case of a null or cyclic parent (duplicate OK)
90
     */
73
     */
91
    public synchronized void append(ClassLoader[] nueparents) throws IllegalArgumentException {
74
    public synchronized void append(ProxyClassLoader[] nueparents) throws IllegalArgumentException {
92
        // XXX should this be synchronized?
75
        // XXX should this be synchronized?
93
        if (nueparents == null) throw new IllegalArgumentException("null parents array"); // NOI18N
76
        if (nueparents == null) throw new IllegalArgumentException("null parents array"); // NOI18N
94
        for (int i = 0; i < nueparents.length; i++) {
77
        for (int i = 0; i < nueparents.length; i++) {
95
            if (nueparents[i] == null) throw new IllegalArgumentException("null parent"); // NOI18N
78
            if (nueparents[i] == null) throw new IllegalArgumentException("null parent"); // NOI18N
96
        }
79
        }
97
        
80
        
98
        parents = coalesceAppend(parents, nueparents);
81
        this.parents = coalesceAppend(parents, nueparents);
82
        parentSet.clear();
83
	parentSet.addAll(Arrays.asList(this.parents));
99
    }
84
    }
100
85
101
    
86
    
102
    
87
//\\    
103
    /** Try to destroy this classloader.
88
    /** Try to destroy this classloader.
104
     * Subsequent attempts to use it will log an error (at most one though).
89
     * Subsequent attempts to use it will log an error (at most one though).
105
     */
90
     */
Lines 120-132 Link Here
120
     * Loads the class with the specified name.  The implementation of
105
     * Loads the class with the specified name.  The implementation of
121
     * this method searches for classes in the following order:<p>
106
     * this method searches for classes in the following order:<p>
122
     * <ol>
107
     * <ol>
123
     * <li> Calls {@link #findLoadedClass(String)} to check if the class has
108
     * <li> Looks for a known package and pass the loading to the ClassLoader
109
            for that package.
110
     * <li> For unknown packages passes the call directly
124
     *      already been loaded.
111
     *      already been loaded.
125
     * <li> Checks the caches whether another class from the same package
126
     *      was already loaded and uses the same classloader
127
     * <li> Tries to find the class using parent loaders in their order.
128
     * <li> Calls the {@link #simpleFindClass} method to find
129
     *      the class using this class loader.
130
     * </ol>
112
     * </ol>
131
     *
113
     *
132
     * @param     name the name of the class
114
     * @param     name the name of the class
Lines 136-150 Link Here
136
     */
118
     */
137
    protected synchronized final Class loadClass(String name, boolean resolve)
119
    protected synchronized final Class loadClass(String name, boolean resolve)
138
                                            throws ClassNotFoundException {
120
                                            throws ClassNotFoundException {
139
        zombieCheck(name);
121
        Class cls = null;
140
        String filename = name.replace('.', '/').concat(".class"); // NOI18N
122
        
141
        int idx = filename.lastIndexOf('/'); // NOI18N
123
	int last = name.lastIndexOf('.');
142
        if (idx == -1) throw new ClassNotFoundException("Will not load classes from default package"); // NOI18N
124
        String pkg = (last >= 0) ? name.substring(0, last) : "";
143
        String pkg = filename.substring(0, idx + 1); // "org/netbeans/modules/foo/"
125
        
144
        Class c = smartLoadClass(name, filename, pkg);
126
	Set del = (Set)packageCoverage.get(pkg);
145
        if(c == null) throw new ClassNotFoundException(name);
127
146
        if (resolve) resolveClass(c);
128
	Boolean boo = (Boolean)sclPackages.get(pkg);
147
        return c;
129
	if (boo == null || boo.booleanValue()) {
130
	    try {
131
        	cls = systemCL.loadClass(name);
132
		if (boo == null) sclPackages.put(pkg, Boolean.TRUE);
133
		return cls; // try SCL first
134
	    } catch (ClassNotFoundException e) {
135
//		sclPackages.put(pkg, Boolean.FALSE); // quite brave assumption
136
	    }
137
	}
138
139
        if (del == null) {
140
            // uncovered package, go directly to SCL
141
            cls = systemCL.loadClass(name);
142
        } else if (del.size() == 1) {
143
            // simple package coverage
144
            ProxyClassLoader pcl = (ProxyClassLoader)del.iterator().next();
145
            if (pcl == this || parentSet.contains(pcl)) {
146
		cls = pcl.selfLoadClass(name);
147
//System.err.println("selfLoadClass(" + pcl + "): " + cls );
148
		if (cls != null) sclPackages.put(pkg, Boolean.FALSE);
149
	    } else { // maybe it is also covered by SCL
150
        	cls = systemCL.loadClass(name);
151
	    }
152
        } else {
153
            // multicovered package, search in order
154
            for (int i=0; i<parents.length; i++) { // all our accessible parents
155
                if (del.contains(parents[i])) { // that cover given package
156
                    cls = parents[i].selfLoadClass(name);
157
                    if (cls != null) break;
158
                }
159
            }
160
	    if (cls == null && del.contains(this)) cls = selfLoadClass(name);
161
	    if (cls != null) sclPackages.put(pkg, Boolean.FALSE);
162
	    if (cls == null) cls = systemCL.loadClass(name); // XXX
163
        }
164
        if(cls == null) throw new ClassNotFoundException(name);
165
        if (resolve) resolveClass(cls);
166
        return cls;
167
    }
168
    
169
    /** May return null */
170
    private synchronized Class selfLoadClass(String name) {
171
        Class cls = findLoadedClass(name);
172
        if (cls == null) cls = doLoadClass(name);
173
        return cls;
148
    }
174
    }
149
    
175
    
150
    /** This ClassLoader can't load anything itself. Subclasses
176
    /** This ClassLoader can't load anything itself. Subclasses
Lines 153-241 Link Here
153
     * <CODE>null</CODE> if it can't load required class.
179
     * <CODE>null</CODE> if it can't load required class.
154
     *
180
     *
155
     * @param  name the name of the class
181
     * @param  name the name of the class
156
     * @param  fileName the expected filename of the classfile, like
157
     *      <CODE>java/lang/Object.class</CODE> for <CODE>java.lang.Object</CODE>
158
     *      The ClassLoader implementation may or may not use it, depending
159
     *      whether it is usefull to it.
160
     * @param pkg the package name, in the format org/netbeans/modules/foo/
161
     * @return the resulting <code>Class</code> object or <code>null</code>
182
     * @return the resulting <code>Class</code> object or <code>null</code>
162
     */
183
     */
163
    protected Class simpleFindClass(String name, String fileName, String pkg) {
184
    protected Class doLoadClass(String name) {
164
        return null;
185
        return null;
165
    }
186
    }
166
    
187
    
167
188
168
    /**
189
    /**
169
     * Finds the resource with the given name. The implementation of
190
     * Finds the resource with the given name.
170
     * this method searches for resources in the following order:<p>
171
     * <ol>
172
     * <li> Checks the caches whether another resource or class from the same
173
     *      package was already loaded and uses the same classloader.
174
     * <li> Tries to find the resources using parent loaders in their order.
175
     * <li> Calls the {@link #findResource(String)} method to find
176
     *      the resources using this class loader.
177
     * </ol>
178
     *
179
     * @param  name a "/"-separated path name that identifies the resource.
191
     * @param  name a "/"-separated path name that identifies the resource.
180
     * @return a URL for reading the resource, or <code>null</code> if
192
     * @return a URL for reading the resource, or <code>null</code> if
181
     *      the resource could not be found.
193
     *      the resource could not be found.
182
     * @see #findResource(String)
194
     * @see #findResource(String)
183
     */
195
     */
184
    public final URL getResource(final String name) {
196
    public final URL getResource(final String name) {
185
        zombieCheck(name);
197
        URL url = null;
186
        
198
        
187
        final int slashIdx = name.lastIndexOf('/');
199
	int last = name.lastIndexOf('/');
188
        if (slashIdx == -1) return null;    // won't load from the default package
200
        String pkg = (last >= 0) ? name.substring(0, last).replace('/', '.') : "";
189
        final String pkg = name.substring(0, slashIdx + 1);
201
	Set del = (Set)packageCoverage.get(pkg);
190
202
191
        if (isSpecialResource(pkg)) {
203
        if (del == null) {
192
            // Disable domain cache for this one, do a simple check.
204
            // uncovered package, go directly to SCL
193
            for (int i = 0; i < parents.length; i++) {
205
            url = systemCL.getResource(name);
194
                if (!shouldDelegateResource(pkg, parents[i])) continue;
206
        } else if (del.size() == 1) {
195
                URL u;
207
            // simple package coverage
196
                if (parents[i] instanceof ProxyClassLoader) {
208
            ProxyClassLoader pcl = (ProxyClassLoader)del.iterator().next();
197
                    u = ((ProxyClassLoader)parents[i]).findResource(name);
209
            if (pcl == this || parentSet.contains(pcl)) url = pcl.findResource(name);
198
                } else {
210
        } else {
199
                    u = parents[i].getResource(name);
211
            // multicovered package, search in order
212
            for (int i=0; i<parents.length; i++) { // all our accessible parents
213
                if (del.contains(parents[i])) { // that cover given package
214
                    url = parents[i].findResource(name);
215
                    if (url != null) break;
200
                }
216
                }
201
                if (u != null) return u;
202
            }
217
            }
203
            return findResource(name);
218
	    if (url == null && del.contains(this)) url = findResource(name);
204
        }
219
        }
205
        
220
        return url;
206
        ClassLoader owner = (ClassLoader)domainsByPackage.get(pkg);
207
208
        if (owner != null) { // known package
209
            // Note that shouldDelegateResource should already be true for this!
210
            if (owner instanceof ProxyClassLoader) {
211
                return ((ProxyClassLoader)owner).findResource(name); // we have its parents, skip them
212
	    } else {
213
                return owner.getResource(name);     // know nothing about this loader and his structure
214
            }
215
        } 
216
        
217
        // virgin package
218
        URL retVal = null;
219
        for (int i = 0; i < parents.length; i++) {
220
            owner = parents[i];
221
            if (!shouldDelegateResource(pkg, owner)) continue;
222
            if (owner instanceof ProxyClassLoader) {
223
                retVal = ((ProxyClassLoader)owner).findResource(name); // skip parents (checked already)
224
            } else {
225
                retVal = owner.getResource(name); // know nothing about this loader and his structure
226
            }
227
            if (retVal != null) {
228
                domainsByPackage.put(pkg, owner);
229
                return retVal;
230
            }
231
        }
232
        
233
        // try it ourself
234
        retVal = findResource(name);
235
        if (retVal != null) {
236
            domainsByPackage.put(pkg, this);
237
        }
238
        return retVal;
239
    }
221
    }
240
222
241
    /** This ClassLoader can't load anything itself. Subclasses
223
    /** This ClassLoader can't load anything itself. Subclasses
Lines 260-285 Link Here
260
     * @throws IOException if I/O errors occur
242
     * @throws IOException if I/O errors occur
261
     */    
243
     */    
262
    protected final synchronized Enumeration findResources(String name) throws IOException {
244
    protected final synchronized Enumeration findResources(String name) throws IOException {
263
        zombieCheck(name);
264
        final int slashIdx = name.lastIndexOf('/');
265
        if (slashIdx == -1) return EMPTY; // won't load from the default package
266
        final String pkg = name.substring(0, slashIdx + 1);
267
268
        // Don't bother optimizing this call by domains.
245
        // Don't bother optimizing this call by domains.
269
        // It is mostly used for resources for which isSpecialResource would be true anyway.
246
        Enumeration[] es = new Enumeration[parents.length + 2];
270
        Enumeration[] es = new Enumeration[parents.length + 1];
247
        es[0] = systemCL.getResources(name);
271
        for (int i = 0; i < parents.length; i++) {
248
        for (int i = 1; i <= parents.length; i++) {
272
            if (!shouldDelegateResource(pkg, parents[i])) {
249
            es[i] = parents[i-1].simpleFindResources(name);
273
                es[i] = EMPTY;
274
                continue;
275
            }
276
            if (parents[i] instanceof ProxyClassLoader) {
277
                es[i] = ((ProxyClassLoader)parents[i]).simpleFindResources(name);
278
            } else {
279
                es[i] = parents[i].getResources(name);
280
            }
281
        }
250
        }
282
        es[parents.length] = simpleFindResources(name);
251
        es[parents.length+1] = simpleFindResources(name);
283
        // Should not be duplicates, assuming the parent loaders are properly distinct
252
        // Should not be duplicates, assuming the parent loaders are properly distinct
284
        // from one another and do not overlap in JAR usage, which they ought not.
253
        // from one another and do not overlap in JAR usage, which they ought not.
285
        // Anyway MetaInfServicesLookup, the most important client of this method, does
254
        // Anyway MetaInfServicesLookup, the most important client of this method, does
Lines 287-301 Link Here
287
        return new AAEnum (es);
256
        return new AAEnum (es);
288
    }
257
    }
289
258
290
    /** This ClassLoader can't load anything itself. Subclasses
291
     * may override this method to do some resource loading themselves, this
292
     * implementation simply delegates to findResources method of the superclass
293
     * that should return empty Enumeration.
294
     *
295
     * @param  name the resource name
296
     * @return an Enumeration of URLs for the resources
297
     * @throws IOException if I/O errors occur
298
     */
299
    protected Enumeration simpleFindResources(String name) throws IOException {
259
    protected Enumeration simpleFindResources(String name) throws IOException {
300
        return super.findResources(name);
260
        return super.findResources(name);
301
    }
261
    }
Lines 309-316 Link Here
309
     * @return the Package corresponding to the given name, or null if not found
269
     * @return the Package corresponding to the given name, or null if not found
310
     */
270
     */
311
    protected Package getPackage(String name) {
271
    protected Package getPackage(String name) {
312
        zombieCheck(name);
272
        return getPackageFast(name, true);
313
        return getPackageFast(name, name.replace('.', '/') + '/', true);
314
    }
273
    }
315
    
274
    
316
    /**
275
    /**
Lines 319-325 Link Here
319
     * @param sname package name in org/netbeans/modules/foo/ format
278
     * @param sname package name in org/netbeans/modules/foo/ format
320
     * @param recurse whether to also ask parents
279
     * @param recurse whether to also ask parents
321
     */
280
     */
322
    protected Package getPackageFast(String name, String sname, boolean recurse) {
281
    protected Package getPackageFast(String name, boolean recurse) {
323
        synchronized (packages) {
282
        synchronized (packages) {
324
            Package pkg = (Package)packages.get(name);
283
            Package pkg = (Package)packages.get(name);
325
            if (pkg != null) {
284
            if (pkg != null) {
Lines 329-343 Link Here
329
                return null;
288
                return null;
330
            }
289
            }
331
            for (int i = 0; i < parents.length; i++) {
290
            for (int i = 0; i < parents.length; i++) {
332
                ClassLoader par = parents[i];
291
                ProxyClassLoader par = parents[i];
333
                if (par instanceof ProxyClassLoader && shouldDelegateResource(sname, par)) {
292
                pkg = par.getPackageFast(name, false);
334
                    pkg = ((ProxyClassLoader)par).getPackageFast(name, sname, false);
293
                if (pkg != null) break;
335
                    if (pkg != null) {
336
                        break;
337
                    }
338
                }
339
            }
294
            }
340
            if (pkg == null && /* #30093 */shouldDelegateResource(sname, getParent())) {
295
            if (pkg == null) {
341
                // Cannot access either Package.getSystemPackage nor ClassLoader.getPackage
296
                // Cannot access either Package.getSystemPackage nor ClassLoader.getPackage
342
                // from here, so do the best we can though it will cause unnecessary
297
                // from here, so do the best we can though it will cause unnecessary
343
                // duplication of the package cache (PCL.packages vs. CL.packages):
298
                // duplication of the package cache (PCL.packages vs. CL.packages):
Lines 374-389 Link Here
374
     * <code>ClassLoader</code>
329
     * <code>ClassLoader</code>
375
     */
330
     */
376
    protected synchronized Package[] getPackages() {
331
    protected synchronized Package[] getPackages() {
377
        zombieCheck(null);
332
	Map all = new HashMap(); // Map<String,Package>
378
        Map all = new HashMap(); // Map<String,Package>
379
        // XXX call shouldDelegateResource on each?
333
        // XXX call shouldDelegateResource on each?
380
        addPackages(all, super.getPackages());
334
        addPackages(all, super.getPackages());
381
        for (int i = 0; i < parents.length; i++) {
335
        for (int i = 0; i < parents.length; i++) {
382
            ClassLoader par = parents[i];
336
            ProxyClassLoader par = parents[i];
383
            if (par instanceof ProxyClassLoader) {
337
            // XXX should ideally use shouldDelegateResource here...
384
                // XXX should ideally use shouldDelegateResource here...
338
            addPackages(all, par.getPackages());
385
                addPackages(all, ((ProxyClassLoader)par).getPackages());
386
            }
387
        }
339
        }
388
        synchronized (packages) {
340
        synchronized (packages) {
389
            Iterator it = all.entrySet().iterator();
341
            Iterator it = all.entrySet().iterator();
Lines 416-435 Link Here
416
     * @return optimized list of parents (no nulls or duplicates)
368
     * @return optimized list of parents (no nulls or duplicates)
417
     * @throws IllegalArgumentException if there are cycles
369
     * @throws IllegalArgumentException if there are cycles
418
     */
370
     */
419
    private ClassLoader[] coalesceParents(ClassLoader[] loaders) throws IllegalArgumentException {
371
    private ProxyClassLoader[] coalesceParents(ProxyClassLoader[] loaders) throws IllegalArgumentException {
420
        int likelySize = loaders.length * 5 + 10;
372
        int likelySize = loaders.length * 5 + 10;
421
        Set resultingUnique = new HashSet(likelySize); // Set<ClassLoader>
373
        Set resultingUnique = new HashSet(likelySize); // Set<ClassLoader>
422
        List resulting = new ArrayList(likelySize); // List<ClassLoader>
374
        List resulting = new ArrayList(likelySize); // List<ClassLoader>
423
        for (int i = 0; i < loaders.length; i++) {
375
        for (int i = 0; i < loaders.length; i++) {
424
            addRec(resultingUnique, resulting, loaders[i]);
376
            addRec(resultingUnique, resulting, loaders[i]);
425
        }
377
        }
426
        ClassLoader[] ret = (ClassLoader[])resulting.toArray(new ClassLoader[resulting.size()]);
378
        ProxyClassLoader[] ret = (ProxyClassLoader[])resulting.toArray(new ProxyClassLoader[resulting.size()]);
427
        return ret;
379
        return ret;
428
    }
380
    }
429
    
381
    
430
    /** Coalesce a new set of loaders into the existing ones.
382
    /** Coalesce a new set of loaders into the existing ones.
431
     */
383
     */
432
    private ClassLoader[] coalesceAppend(ClassLoader[] existing, ClassLoader[] appended) throws IllegalArgumentException {
384
    private ProxyClassLoader[] coalesceAppend(ProxyClassLoader[] existing, ProxyClassLoader[] appended) throws IllegalArgumentException {
433
        int likelySize = existing.length + 3;
385
        int likelySize = existing.length + 3;
434
        Set resultingUnique = new HashSet(likelySize);
386
        Set resultingUnique = new HashSet(likelySize);
435
        List existingL = Arrays.asList(existing);
387
        List existingL = Arrays.asList(existing);
Lines 443-457 Link Here
443
        for (int i = 0; i < appended.length; i++) {
395
        for (int i = 0; i < appended.length; i++) {
444
            addRec(resultingUnique, resulting, appended[i]);
396
            addRec(resultingUnique, resulting, appended[i]);
445
        }
397
        }
446
        ClassLoader[] ret = (ClassLoader[])resulting.toArray(new ClassLoader[resulting.size()]);
398
        ProxyClassLoader[] ret = (ProxyClassLoader[])resulting.toArray(new ProxyClassLoader[resulting.size()]);
447
        return ret;
399
        return ret;
448
    }
400
    }   
449
    
401
    
450
    private void addRec(Set resultingUnique, List resulting, ClassLoader loader) throws IllegalArgumentException {
402
    private void addRec(Set resultingUnique, List resulting, ProxyClassLoader loader) throws IllegalArgumentException {
451
        if (loader == this) throw new IllegalArgumentException("cycle in parents"); // NOI18N
403
        if (loader == this) throw new IllegalArgumentException("cycle in parents"); // NOI18N
452
        if (resultingUnique.contains(loader)) return;
404
        if (resultingUnique.contains(loader)) return;
453
        if (loader instanceof ProxyClassLoader && ((ProxyClassLoader)loader).transitive) {
405
        if (loader.transitive) {
454
            ClassLoader[] parents = ((ProxyClassLoader)loader).parents;
406
            ProxyClassLoader[] parents = loader.parents;
455
            for (int i = 0; i < parents.length; i++) {
407
            for (int i = 0; i < parents.length; i++) {
456
                addRec(resultingUnique, resulting, parents[i]);
408
                addRec(resultingUnique, resulting, parents[i]);
457
            }
409
            }
Lines 460-596 Link Here
460
        resulting.add(loader);
412
        resulting.add(loader);
461
    }
413
    }
462
414
463
    /** A method that finds a class either in itself or in parents.
464
     * It uses dual signaling for class not found: it can either return null
465
     * or throw CNFE itself.
466
     * @param name class name, e.g. "org.netbeans.modules.foo.Clazz"
467
     * @param fileName resource name, e.g. "org/netbeans/modules/foo/Clazz.class"
468
     * @param pkg package component, e.g. "org/netbeans/modules/foo/"
469
     * @return a class or null if not found. It can also throw an exception.
470
     * @throws ClassNotFoundException in case it doesn't found a class
471
     * and a parent eglible for loading it thrown it already.
472
     */
473
    private final Class smartLoadClass(String name, String fileName, String pkg) throws ClassNotFoundException {
474
	// First, check if the class has already been loaded
475
	Class c = findLoadedClass(name);
476
	if(c != null) return c;
477
        
478
        final ClassLoader owner = isSpecialResource(pkg) ? null : (ClassLoader)domainsByPackage.get(pkg);
479
        if (owner == this) {
480
            return simpleFindClass(name, fileName, pkg);
481
        }
482
        if (owner != null) {
483
            // Note that shouldDelegateResource should already be true as we hit this pkg before.
484
            if (owner instanceof ProxyClassLoader) {
485
                return ((ProxyClassLoader)owner).fullFindClass(name, fileName, pkg);
486
            } else {
487
                return owner.loadClass(name); // May throw CNFE, will be propagated
488
            }
489
        }
490
        
491
        // Virgin package, do the parent scan 
492
        c = loadInOrder(name, fileName, pkg);
493
494
        if (c != null) {
495
            final ClassLoader owner2 = getClassClassLoader(c); // who got it?
496
            domainsByPackage.put(pkg, owner2);
497
        }
498
        return c;
499
    }
500
501
    // #29844 run as privileged as it may get called by loadClassInternal() used
502
    // during class resolving by JVM with arbitrary ProtectionDomain context stack
503
    private static ClassLoader getClassClassLoader(final Class c) {
504
        return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
505
            public Object run() {
506
                return c.getClassLoader();
507
            }
508
        });
509
    }
510
511
    private final Class loadInOrder( String name, String fileName, String pkg ) throws ClassNotFoundException {
512
        ClassNotFoundException cached = null;
513
        for (int i = 0; i < parents.length; i++) {
514
	    ClassLoader par = parents[i];
515
            if (!shouldDelegateResource(pkg, par)) continue;
516
	    if (par instanceof ProxyClassLoader) {
517
                ProxyClassLoader pcl = (ProxyClassLoader)par;
518
		Class c = pcl.fullFindClass(name, fileName, pkg);
519
                // pcl might have have c in its already-loaded classes even though
520
                // it was not the defining class loader. In that case, if pcl was
521
                // not transitive (should not expose its own parents), reject this.
522
                if (c != null && (pcl.transitive || getClassClassLoader(c) == pcl)) return c;
523
	    } else {
524
                // The following is an optimization, it should not affect semantics:
525
                boolean skip = false;
526
                if (name.startsWith("org.netbeans.") || // NOI18N
527
                        name.startsWith("org.openide.") || // NOI18N
528
                        name.endsWith(".Bundle") || // NOI18N
529
                        name.endsWith("BeanInfo") || // NOI18N
530
                        name.endsWith("Editor")) { // NOI18N
531
                    if (par.getResource(fileName) == null) {
532
                        // We would just throw CNFE anyway, don't bother!
533
                        // Avg. (over ten runs after primer, w/ netbeans.close):
534
                        // before: 13.87s after: 13.40s saved: 1.3%
535
                        skip = true;
536
                    }
537
                }
538
                if (!skip) {
539
                    try {
540
                        return par.loadClass(name);
541
                    } catch( ClassNotFoundException cnfe ) {
542
                        cached = cnfe;
543
                    }
544
                }
545
	    }
546
	}
547
548
        Class c = simpleFindClass(name, fileName, pkg); // Try it ourselves
549
        if (c != null) return c;
550
        if (cached != null) throw cached;
551
	return null;
552
    }
553
554
    private synchronized Class fullFindClass(String name, String fileName, String pkg) {
555
	Class c = findLoadedClass(name);
556
	return (c == null) ? simpleFindClass(name, fileName, pkg) : c;
557
    }    
558
559
    private void addPackages(Map all, Package[] pkgs) {
415
    private void addPackages(Map all, Package[] pkgs) {
560
        // Would be easier if Package.equals() was just defined sensibly...
416
        // Would be easier if Package.equals() was just defined sensibly...
561
        for (int i = 0; i < pkgs.length; i++) {
417
        for (int i = 0; i < pkgs.length; i++) {
562
            all.put(pkgs[i].getName(), pkgs[i]);
418
            all.put(pkgs[i].getName(), pkgs[i]);
563
        }
419
        }
564
    }
565
    
566
    /** Test whether a given resource name is something that any JAR might
567
     * have, and for which the domain cache should be disabled.
568
     * The result must not change from one call to the next with the same argument.
569
     * By default the domain cache is disabled only for META-INF/* JAR information.
570
     * @param pkg the package component of the resource path ending with a slash,
571
     *        e.g. "org/netbeans/modules/foo/"
572
     * @return true if it is a special resource, false for normal domain-cached resource
573
     * @since org.netbeans.core/1 1.3
574
     */
575
    protected boolean isSpecialResource(String pkg) {
576
        if (pkg.startsWith("META-INF/")) return true; // NOI18N
577
        return false;
578
    }
579
    
580
    /** Test whether a given resource request (for a class or not) should be
581
     * searched for in the specified parent classloader or not.
582
     * The result must not change from one call to the next with the same arguments.
583
     * By default, always true. Subclasses may override to "mask" certain
584
     * packages from view, possibly according to the classloader chain.
585
     * @param pkg the package component of the resource path ending with a slash,
586
     *        e.g. "org/netbeans/modules/foo/"
587
     * @param parent a classloader which is a direct or indirect parent of this one
588
     * @return true if the request should be delegated to this parent; false to
589
     *         only search elsewhere (other parents, this loader's own namespace)
590
     * @since org.netbeans.core/1 1.3
591
     */
592
    protected boolean shouldDelegateResource(String pkg, ClassLoader parent) {
593
        return true;
594
    }
420
    }
595
    
421
    
596
    
422
    
(-)src/org/netbeans/core/modules/Module.java (-9 / +10 lines)
Lines 947-953 Link Here
947
        mgr.refineClassLoader(this, loaders);
947
        mgr.refineClassLoader(this, loaders);
948
        
948
        
949
        try {
949
        try {
950
            classloader = new OneModuleClassLoader(classp, (ClassLoader[])loaders.toArray(new ClassLoader[loaders.size()]));
950
            classloader = new OneModuleClassLoader(classp, (ProxyClassLoader[])loaders.toArray(new ProxyClassLoader[loaders.size()]));
951
        } catch (IllegalArgumentException iae) {
951
        } catch (IllegalArgumentException iae) {
952
            // Should not happen, but just in case.
952
            // Should not happen, but just in case.
953
            IOException ioe = new IOException(iae.toString());
953
            IOException ioe = new IOException(iae.toString());
Lines 960-968 Link Here
960
    /** Turn off the classloader and release all resources. */
960
    /** Turn off the classloader and release all resources. */
961
    void classLoaderDown() {
961
    void classLoaderDown() {
962
        if (isFixed()) return; // don't touch it
962
        if (isFixed()) return; // don't touch it
963
        if (classloader instanceof ProxyClassLoader) {
963
//        if (classloader instanceof ProxyClassLoader) {
964
            ((ProxyClassLoader)classloader).destroy();
964
//            ((ProxyClassLoader)classloader).destroy();
965
        }
965
//        }
966
        classloader = null;
966
        classloader = null;
967
        Util.err.log("classLoaderDown on " + this + ": releaseCount=" + releaseCount + " released=" + released);
967
        Util.err.log("classLoaderDown on " + this + ": releaseCount=" + releaseCount + " released=" + released);
968
        released = false;
968
        released = false;
Lines 1078-1084 Link Here
1078
         *      The items are JarFiles for jars and Files for directories
1078
         *      The items are JarFiles for jars and Files for directories
1079
         * @param parents a set of parent classloaders (from other modules)
1079
         * @param parents a set of parent classloaders (from other modules)
1080
         */
1080
         */
1081
        public OneModuleClassLoader(List classp, ClassLoader[] parents) throws IllegalArgumentException {
1081
        public OneModuleClassLoader(List classp, ProxyClassLoader[] parents) throws IllegalArgumentException {
1082
            super(classp, parents, false);
1082
            super(classp, parents, false);
1083
            rc = releaseCount++;
1083
            rc = releaseCount++;
1084
        }
1084
        }
Lines 1110-1122 Link Here
1110
            if (mgr.isSpecialResource(pkg)) {
1110
            if (mgr.isSpecialResource(pkg)) {
1111
                return true;
1111
                return true;
1112
            }
1112
            }
1113
            return super.isSpecialResource(pkg);
1113
	    return false;
1114
//            return super.isSpecialResource(pkg);
1114
        }
1115
        }
1115
        
1116
        
1116
        protected boolean shouldDelegateResource(String pkg, ClassLoader parent) {
1117
        protected boolean shouldDelegateResource(String pkg, ClassLoader parent) {
1117
            if (!super.shouldDelegateResource(pkg, parent)) {
1118
//            if (!super.shouldDelegateResource(pkg, parent)) {
1118
                return false;
1119
//                return false;
1119
            }
1120
//            }
1120
            Module other;
1121
            Module other;
1121
            if (parent instanceof Util.ModuleProvider) {
1122
            if (parent instanceof Util.ModuleProvider) {
1122
                other = ((Util.ModuleProvider)parent).getModule();
1123
                other = ((Util.ModuleProvider)parent).getModule();
(-)src/org/netbeans/core/modules/ModuleManager.java (-15 / +34 lines)
Lines 34-39 Link Here
34
import org.openide.modules.Dependency;
34
import org.openide.modules.Dependency;
35
import org.openide.ErrorManager;
35
import org.openide.ErrorManager;
36
import org.netbeans.JarClassLoader;
36
import org.netbeans.JarClassLoader;
37
import org.netbeans.ProxyClassLoader;
37
38
38
/** Manages a collection of modules.
39
/** Manages a collection of modules.
39
 * Must use {@link #mutex} to access its important methods.
40
 * Must use {@link #mutex} to access its important methods.
Lines 96-102 Link Here
96
            // Normal case.
97
            // Normal case.
97
            classLoaderPatches = Collections.EMPTY_LIST;
98
            classLoaderPatches = Collections.EMPTY_LIST;
98
        }
99
        }
99
        classLoader = new SystemClassLoader(classLoaderPatches, new ClassLoader[] {ModuleManager.class.getClassLoader()}, Collections.EMPTY_SET);
100
        classLoader = new SystemClassLoader(classLoaderPatches, new ProxyClassLoader[] {(ProxyClassLoader)ModuleManager.class.getClassLoader()}, Collections.EMPTY_SET);
100
        updateContextClassLoaders(classLoader, true);
101
        updateContextClassLoaders(classLoader, true);
101
    }
102
    }
102
    
103
    
Lines 293-299 Link Here
293
        // it is likely that some of these classloaders will overlap.
294
        // it is likely that some of these classloaders will overlap.
294
        Set foundParents = new HashSet(modules.size() * 4 / 3 + 2); // Set<ClassLoader>
295
        Set foundParents = new HashSet(modules.size() * 4 / 3 + 2); // Set<ClassLoader>
295
        List parents = new ArrayList(modules.size() + 1); // List<ClassLoader>
296
        List parents = new ArrayList(modules.size() + 1); // List<ClassLoader>
296
        ClassLoader base = ModuleManager.class.getClassLoader();
297
        ProxyClassLoader base = (ProxyClassLoader)ModuleManager.class.getClassLoader();
297
        foundParents.add(base);
298
        foundParents.add(base);
298
        parents.add(base);
299
        parents.add(base);
299
        Iterator it = modules.iterator();
300
        Iterator it = modules.iterator();
Lines 306-318 Link Here
306
                parents.add(m.getClassLoader());
307
                parents.add(m.getClassLoader());
307
            }
308
            }
308
        }
309
        }
309
        ClassLoader[] parentCLs = (ClassLoader[])parents.toArray(new ClassLoader[parents.size()]);
310
        ProxyClassLoader[] parentCLs = (ProxyClassLoader[])parents.toArray(new ProxyClassLoader[parents.size()]);
310
        SystemClassLoader nue;
311
        SystemClassLoader nue;
311
        try {
312
        try {
312
            nue = new SystemClassLoader(classLoaderPatches, parentCLs, modules);
313
            nue = new SystemClassLoader(classLoaderPatches, parentCLs, modules);
313
        } catch (IllegalArgumentException iae) {
314
        } catch (IllegalArgumentException iae) {
314
            Util.err.notify(iae);
315
            Util.err.notify(iae);
315
            nue = new SystemClassLoader(classLoaderPatches, new ClassLoader[] {ModuleManager.class.getClassLoader()}, Collections.EMPTY_SET);
316
            nue = new SystemClassLoader(classLoaderPatches, new ProxyClassLoader[] {(ProxyClassLoader)ModuleManager.class.getClassLoader()}, Collections.EMPTY_SET);
316
        }
317
        }
317
        synchronized (classLoaderLock) {
318
        synchronized (classLoaderLock) {
318
            classLoader = nue;
319
            classLoader = nue;
Lines 362-368 Link Here
362
        private final StringBuffer debugme;
363
        private final StringBuffer debugme;
363
        private boolean empty = true;
364
        private boolean empty = true;
364
        
365
        
365
        public SystemClassLoader(List files, ClassLoader[] parents, Set modules) throws IllegalArgumentException {
366
        public SystemClassLoader(List files, ProxyClassLoader[] parents, Set modules) throws IllegalArgumentException {
366
            super(files, parents, false);
367
            super(files, parents, false);
367
            allPermissions = new Permissions();
368
            allPermissions = new Permissions();
368
            allPermissions.add(new AllPermission());
369
            allPermissions.add(new AllPermission());
Lines 402-408 Link Here
402
            }
403
            }
403
        }
404
        }
404
        
405
        
405
        public void append(ClassLoader[] ls, List modules) throws IllegalArgumentException {
406
        public void append(ProxyClassLoader[] ls, List modules) throws IllegalArgumentException {
406
            super.append(ls);
407
            super.append(ls);
407
            debugme.deleteCharAt(debugme.length() - 1);
408
            debugme.deleteCharAt(debugme.length() - 1);
408
            record(modules);
409
            record(modules);
Lines 422-428 Link Here
422
            if (installer.isSpecialResource(pkg)) {
423
            if (installer.isSpecialResource(pkg)) {
423
                return true;
424
                return true;
424
            }
425
            }
425
            return super.isSpecialResource(pkg);
426
//            return super.isSpecialResource(pkg);
427
return false;
426
        }
428
        }
427
        
429
        
428
        /** Provide all permissions for any code loaded from the files list
430
        /** Provide all permissions for any code loaded from the files list
Lines 431-436 Link Here
431
        protected PermissionCollection getPermissions(CodeSource cs) {
433
        protected PermissionCollection getPermissions(CodeSource cs) {
432
            return allPermissions;
434
            return allPermissions;
433
        }
435
        }
436
//<<<<
437
        protected URL fileToURL(File f) throws MalformedURLException {
438
            return Utilities.toURL(f);
439
        }
440
441
private long resTime;
442
private long clTime;
443
444
//	public URL getResource(String name) {
445
//	    long time = System.currentTimeMillis();
446
//	    URL ret = super.getResource(name);
447
//	    time = System.currentTimeMillis() - time;
448
//	    resTime += time;
449
//System.err.println("  SCL.getResource(" + name + " took " + time + "ms, total=" + resTime + "ms");
450
//	    return ret;
451
//	}
434
452
435
    }
453
    }
436
454
Lines 753-759 Link Here
753
                    Module m = (Module)teIt.next();
771
                    Module m = (Module)teIt.next();
754
                    fallback.addFirst(m);
772
                    fallback.addFirst(m);
755
                    Util.err.log("enable: bringing up: " + m);
773
                    Util.err.log("enable: bringing up: " + m);
756
                    ev.log(Events.PERF_START, "bringing up classloader on " + m.getCodeName() ); // NOI18N
774
//                    ev.log(Events.PERF_START, "bringing up classloader on " + m.getCodeName() ); // NOI18N
757
                    try {
775
                    try {
758
                        // Calculate the parents to initialize the classloader with.
776
                        // Calculate the parents to initialize the classloader with.
759
                        Dependency[] dependencies = m.getDependenciesArray();
777
                        Dependency[] dependencies = m.getDependenciesArray();
Lines 780-788 Link Here
780
                        throw ie;
798
                        throw ie;
781
                    }
799
                    }
782
                    m.setEnabled(true);
800
                    m.setEnabled(true);
783
                    ev.log(Events.PERF_END, "bringing up classloader on " + m.getCodeName() ); // NOI18N
801
//                    ev.log(Events.PERF_END, "bringing up classloader on " + m.getCodeName() ); // NOI18N
784
                    // Check package dependencies.
802
                    // Check package dependencies.
785
                    ev.log(Events.PERF_START, "package dependency check on " + m.getCodeName() ); // NOI18N
803
//                    ev.log(Events.PERF_START, "package dependency check on " + m.getCodeName() ); // NOI18N
786
                    Util.err.log("enable: checking package dependencies for " + m);
804
                    Util.err.log("enable: checking package dependencies for " + m);
787
                    Dependency[] dependencies = m.getDependenciesArray();
805
                    Dependency[] dependencies = m.getDependenciesArray();
788
                    for (int i = 0; i < dependencies.length; i++) {
806
                    for (int i = 0; i < dependencies.length; i++) {
Lines 796-806 Link Here
796
                        }
814
                        }
797
                        Util.err.log("Successful check for: " + dep);
815
                        Util.err.log("Successful check for: " + dep);
798
                    }
816
                    }
799
                    ev.log(Events.PERF_END, "package dependency check on " + m.getCodeName() ); // NOI18N
817
//                    ev.log(Events.PERF_END, "package dependency check on " + m.getCodeName() ); // NOI18N
800
                    // Prepare to load it.
818
                    // Prepare to load it.
801
                    ev.log(Events.PERF_START, "ModuleInstaller.prepare " + m.getCodeName() ); // NOI18N
819
//                    ev.log(Events.PERF_START, "ModuleInstaller.prepare " + m.getCodeName() ); // NOI18N
802
                    installer.prepare(m);
820
                    installer.prepare(m);
803
                    ev.log(Events.PERF_END, "ModuleInstaller.prepare " + m.getCodeName() ); // NOI18N
821
//                    ev.log(Events.PERF_END, "ModuleInstaller.prepare " + m.getCodeName() ); // NOI18N
822
                    ev.log(Events.PERF_TICK, "ModuleInstaller.prepare " + m.getCodeName() ); // NOI18N
804
                }
823
                }
805
                ev.log(Events.PERF_END, "module preparation" ); // NOI18N
824
                ev.log(Events.PERF_END, "module preparation" ); // NOI18N
806
825
Lines 817-823 Link Here
817
                    probs.add(failedPackageDep);
836
                    probs.add(failedPackageDep);
818
                } else {
837
                } else {
819
                    // Some other problem (exception).
838
                    // Some other problem (exception).
820
                    probs.add(ie);
839
                    probs.add(ie); 
821
                }
840
                }
822
                // Other modules may have depended on this one and now will not be OK.
841
                // Other modules may have depended on this one and now will not be OK.
823
                // So clear all "soft" problems from the cache.
842
                // So clear all "soft" problems from the cache.
Lines 853-859 Link Here
853
                while (teIt.hasNext()) {
872
                while (teIt.hasNext()) {
854
                    nueclassloaders.add(((Module)teIt.next()).getClassLoader());
873
                    nueclassloaders.add(((Module)teIt.next()).getClassLoader());
855
                }
874
                }
856
                classLoader.append((ClassLoader[])(nueclassloaders.toArray(new ClassLoader[nueclassloaders.size()])), toEnable);
875
                classLoader.append((ProxyClassLoader[])(nueclassloaders.toArray(new ProxyClassLoader[nueclassloaders.size()])), toEnable);
857
            } else {
876
            } else {
858
                Util.err.log("enable: no class loader yet, not appending");
877
                Util.err.log("enable: no class loader yet, not appending");
859
            }
878
            }

Return to bug 30971