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 29339
Collapse All | Expand All

(-)core/bootstrap/src/org/netbeans/ProxyClassLoader.java (-33 / +137 lines)
Lines 112-148 Link Here
112
        }
112
        }
113
    }
113
    }
114
114
115
    /**
115
  protected static char[] namescratch = new char[115];
116
     * Loads the class with the specified name.  The implementation of
116
  //needs to be big enough to accomodate
117
     * this method searches for classes in the following order:<p>
117
  //org.netbeans.modules.properties.syntax.PropertiesSettingsInitializer$PropertiesTokenColoringInitializer.class
118
     * <ol>
118
  protected static char[] pkgscratch = new char[90];
119
     * <li> Calls {@link #findLoadedClass(String)} to check if the class has
119
  //These arrays are sized > longest neede name for NetBeans - 
120
     *      already been loaded.
120
  
121
     * <li> Checks the caches whether another class from the same package
121
  //org.netbeans.modules.projects.CurrentProjectNode$Explorer$MiniStatusBarStateListener.class
122
     *      was already loaded and uses the same classloader
122
  private static final char[] clazzext = new char[] {'.','c','l','a','s','s'};
123
     * <li> Tries to find the class using parent loaders in their order.
123
  protected synchronized final Class loadClass(String name, boolean resolve)
124
     * <li> Calls the {@link #simpleFindClass(String,String)} method to find
125
     *      the class using this class loader.
126
     * </ol>
127
     *
128
     * @param     name the name of the class
129
     * @param     resolve if <code>true</code> then resolve the class
130
     * @return	  the resulting <code>Class</code> object
131
     * @exception ClassNotFoundException if the class could not be found
132
     */
133
    protected synchronized final Class loadClass(String name, boolean resolve)
134
                                            throws ClassNotFoundException {
124
                                            throws ClassNotFoundException {
135
        zombieCheck(name);
125
        zombieCheck(name);
136
        String filename = name.replace('.', '/').concat(".class"); // NOI18N
126
        /* The following code is an heavy optimization of 
137
        int idx = filename.lastIndexOf('/'); // NOI18N
127
           String filename = name.replace('.', '/').concat(".class"); // NOI18N
138
        if (idx == -1) throw new ClassNotFoundException("Will not load classes from default package"); // NOI18N
128
           int idx = filename.lastIndexOf('/'); // NOI18N
139
        String pkg = filename.substring(0, idx + 1); // "org/netbeans/modules/foo/"
129
           to improve performance and reduce memory allocation.
140
        Class c = smartLoadClass(name, filename, pkg);
130
         */
131
        int nlen = name.length();
132
        //create an array with room for .class
133
        int end = nlen +6;
134
        //copy the constant char array here
135
        //copy the name into the beginning of the array
136
        try {
137
            name.getChars(0, nlen, namescratch, 0);
138
        } catch (ArrayIndexOutOfBoundsException ae1) {
139
            namescratch = new char[nlen + 20];
140
            name.getChars(0, nlen, namescratch, 0);
141
        }
142
        //quickly scan backwards and find the last occurance of '.' &
143
        //save the result
144
        int idx = nlen-1;
145
        for (;(idx >= 0) && (namescratch[idx] != '.'); idx--) {
146
            //empty impl
147
        }
148
        if (idx < 0) throw new ClassNotFoundException("Will not load classes from default package - " + name); // NOI18N
149
        //since we know about it already, set the final . to / now
150
        namescratch[idx] = '/';
151
//        idx++;
152
        
153
        try {
154
            //iterate forward up to package name boundary, skipping 
155
            //the one we already set and the preceding character (if that
156
            //is / or . we have an illegal package name and it will be 
157
            //caught later, so doesn't matter). Overflowing doesn't matter, we
158
            //will only copy up to the value of the end field, and any
159
            //inadvertent modifications will be overwritten by '.class'.
160
            for (int j=0; j < idx; j+=5) {
161
                namescratch[j] = namescratch[j] == '.' ? '/' : namescratch[j];
162
                namescratch[j+1] = namescratch[j+1] == '.' ? '/' : namescratch[j+1];
163
                namescratch[j+2] = namescratch[j+2] == '.' ? '/' : namescratch[j+2];
164
                namescratch[j+3] = namescratch[j+3] == '.' ? '/' : namescratch[j+3];
165
                namescratch[j+4] = namescratch[j+4] == '.' ? '/' : namescratch[j+4];
166
            }
167
        } catch (ArrayIndexOutOfBoundsException e) {
168
            //on the rare occasion that it won't fit, reallocate and do it again
169
            char[] old = namescratch;
170
            namescratch = new char[old.length + 20];
171
            System.arraycopy (old, 0, namescratch, 0, old.length);
172
            //do it the slow way, won't happen often if at all
173
            for (int j1=0; j1 < idx; j1++) {
174
                if (namescratch[j1] == '.') namescratch[j1]='/';
175
            }
176
        }
177
178
        //now copy in the .class extension
179
        try {
180
            System.arraycopy(clazzext, 0, namescratch, nlen, 6);
181
        } catch (ArrayIndexOutOfBoundsException ae) {
182
            //on the off chance a name is too long, grow the array.
183
            //Shouldn't happen often if at all
184
            char[] oldscratch = namescratch;
185
            namescratch = new char[end+10];
186
            System.arraycopy (oldscratch, 0, namescratch, 0, oldscratch.length); 
187
            System.arraycopy(clazzext, 0, namescratch, nlen, 6);
188
        }
189
        //allocate the strings
190
        String pkg = new String (namescratch,0,idx+1);  // "org/netbeans/modules/foo/"
191
        String fullname = new String (namescratch,0,end);   // "org/netbeans/modules/foo/MyClass.class"
192
        //end of string optimization
193
        Class c = smartLoadClass(name, fullname, pkg);
141
        if(c == null) throw new ClassNotFoundException(name);
194
        if(c == null) throw new ClassNotFoundException(name);
142
        if (resolve) resolveClass(c);
195
        if (resolve) resolveClass(c);
143
        return c;
196
        return c;
144
    }
197
  }    
145
    
146
    /** This ClassLoader can't load anything itself. Subclasses
198
    /** This ClassLoader can't load anything itself. Subclasses
147
     * may override this method to do some class loading themselves. The
199
     * may override this method to do some class loading themselves. The
148
     * implementation should not throw any exception, just return
200
     * implementation should not throw any exception, just return
Lines 295-301 Link Here
295
        return super.findResources(name);
347
        return super.findResources(name);
296
    }
348
    }
297
349
298
    
299
    /**
350
    /**
300
     * Returns a Package that has been defined by this class loader or any
351
     * Returns a Package that has been defined by this class loader or any
301
     * of its parents.
352
     * of its parents.
Lines 305-319 Link Here
305
     */
356
     */
306
    protected Package getPackage(String name) {
357
    protected Package getPackage(String name) {
307
        zombieCheck(name);
358
        zombieCheck(name);
308
        
359
        Package pkg=null;
360
        synchronized (packages) {
361
            pkg=(Package) packages.get(name);
362
            if (pkg != null) return pkg;
363
        }
364
        //below is the original code for string handling;
365
        //the code in the synchronized block following
366
        //accomplishes the same thing, but is optimized to
367
        //reduce String array copies and is about 40% faster
368
        /*
309
        int idx = name.lastIndexOf('.');
369
        int idx = name.lastIndexOf('.');
310
        if (idx == -1) return null;
370
        if (idx == -1) return null;
311
        String spkg = name.substring(0, idx + 1).replace('.', '/');
371
        String spkg = name.substring(0, idx + 1).replace('.', '/');
312
        
372
        */
313
	synchronized (packages) {
373
        String spkg; 
314
	    Package pkg = (Package)packages.get(name);
374
        int nlen = name.length();
315
            if (pkg != null) return pkg;
375
        //is this synchronization necessary?  Probably.  Works
316
            
376
        //without it, but that's on a uniprocessor machine.  If sure
377
        //it is a non-issue, remove.
378
        synchronized (pkgscratch) {
379
            try {
380
                //load the name into the scratch array
381
                name.getChars(0, nlen-1, pkgscratch, 0);
382
            } catch (ArrayIndexOutOfBoundsException ae) {
383
                //if the array is too small, grow it and try again
384
                pkgscratch = new char[nlen+20];
385
                name.getChars(0, nlen-1, pkgscratch, 0);
386
            }
387
            //start at the end of the array and iterate back until
388
            // a '.' is found.
389
            int idx=nlen-1;
390
	    for (; (idx >= 0) && (pkgscratch[idx] != '.'); idx--) {
391
		//empty impl-we just want the value of idx
392
		}
393
                
394
            //now iterate the array as far as necessary, replacing
395
            //'.' with '/' - we'll set the last char (known) explicitly below
396
            try {
397
		for (int i=0; i <= idx-5; i+=4) {
398
       		    if (pkgscratch[i] == '.') pkgscratch[i] = '/';
399
		    if (pkgscratch[i+1] == '.') pkgscratch[i+1] = '/';
400
		    if (pkgscratch[i+2] == '.') pkgscratch[i+2] = '/';
401
		    if (pkgscratch[i+3] == '.') pkgscratch[i+3] = '/'; 
402
		}
403
	    } catch (ArrayIndexOutOfBoundsException ae2) {
404
                //Faint possibility of overflowing
405
                //if we need to grow the array, we've got one honkin' big package name
406
                char[] oldscratch = pkgscratch;
407
                pkgscratch=new char[pkgscratch.length + 20];
408
                System.arraycopy (oldscratch, 0 , pkgscratch, 0, oldscratch.length);
409
                for (int n = 0; n < idx; n++) {
410
       		    if (pkgscratch[n] == '.') pkgscratch[n] = '/';
411
                }
412
	    }
413
            //if we're not in the default package, explicitly set the
414
            //final trailing slash
415
	    if (idx >=0) pkgscratch[idx] = '/';
416
            //create the result string
417
	    spkg = idx == -1 ? "" : new String (pkgscratch, 0, idx+1);
418
        }
419
        //end of optimized string loading
420
        synchronized (packages) {
317
            for (int i = 0; i < parents.length; i++) {
421
            for (int i = 0; i < parents.length; i++) {
318
                ClassLoader par = parents[i];
422
                ClassLoader par = parents[i];
319
                if (par instanceof ProxyClassLoader && shouldDelegateResource(spkg, par)) {
423
                if (par instanceof ProxyClassLoader && shouldDelegateResource(spkg, par)) {

Return to bug 29339