91 * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
92 * class or resource to its parent class loader before attempting to find the
93 * class or resource itself. The virtual machine's built-in class loader,
94 * called the "bootstrap class loader", does not itself have a parent but may
95 * serve as the parent of a <tt>ClassLoader</tt> instance.
96 *
97 * <p> Class loaders that support concurrent loading of classes are known as
98 * <em>parallel capable</em> class loaders and are required to register
99 * themselves at their class initialization time by invoking the
100 * {@link
101 * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
102 * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
103 * capable by default. However, its subclasses still need to register themselves
104 * if they are parallel capable. <br>
105 * In environments in which the delegation model is not strictly
106 * hierarchical, class loaders need to be parallel capable, otherwise class
107 * loading can lead to deadlocks because the loader lock is held for the
108 * duration of the class loading process (see {@link #loadClass
109 * <tt>loadClass</tt>} methods).
110 *
111 * <p> Normally, the Java virtual machine loads classes from the local file
112 * system in a platform-dependent manner. For example, on UNIX systems, the
113 * virtual machine loads classes from the directory defined by the
114 * <tt>CLASSPATH</tt> environment variable.
115 *
116 * <p> However, some classes may not originate from a file; they may originate
117 * from other sources, such as the network, or they could be constructed by an
118 * application. The method {@link #defineClass(String, byte[], int, int)
119 * <tt>defineClass</tt>} converts an array of bytes into an instance of class
120 * <tt>Class</tt>. Instances of this newly defined class can be created using
121 * {@link Class#newInstance <tt>Class.newInstance</tt>}.
122 *
123 * <p> The methods and constructors of objects created by a class loader may
124 * reference other classes. To determine the class(es) referred to, the Java
125 * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
126 * the class loader that originally created the class.
127 *
128 * <p> For example, an application could create a network class loader to
129 * download class files from a server. Sample code might look like:
130 *
176 */
177 public abstract class ClassLoader {
178
179 private static native void registerNatives();
180 static {
181 registerNatives();
182 }
183
184 // The parent class loader for delegation
185 // Note: VM hardcoded the offset of this field, thus all new fields
186 // must be added *after* it.
187 private final ClassLoader parent;
188
189 /**
190 * Encapsulates the set of parallel capable loader types.
191 */
192 private static class ParallelLoaders {
193 private ParallelLoaders() {}
194
195 // the set of parallel capable loader types
196 private static final Set<Class<? extends ClassLoader>> loaderTypes =
197 Collections.newSetFromMap(
198 new WeakHashMap<Class<? extends ClassLoader>, Boolean>());
199 static {
200 synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); }
201 }
202
203 /**
204 * Registers the given class loader type as parallel capabale.
205 * Returns {@code true} is successfully registered; {@code false} if
206 * loader's super class is not registered.
207 */
208 static boolean register(Class<? extends ClassLoader> c) {
209 synchronized (loaderTypes) {
210 if (loaderTypes.contains(c.getSuperclass())) {
211 // register the class loader as parallel capable
212 // if and only if all of its super classes are.
213 // Note: given current classloading sequence, if
214 // the immediate super class is parallel capable,
215 // all the super classes higher up must be too.
216 loaderTypes.add(c);
217 return true;
218 } else {
219 return false;
220 }
221 }
222 }
223
224 /**
225 * Returns {@code true} if the given class loader type is
226 * registered as parallel capable.
227 */
228 static boolean isRegistered(Class<? extends ClassLoader> c) {
229 synchronized (loaderTypes) {
230 return loaderTypes.contains(c);
231 }
232 }
233 }
234
235 // Maps class name to the corresponding lock object when the current
236 // class loader is parallel capable.
237 // Note: VM also uses this field to decide if the current class loader
238 // is parallel capable and the appropriate lock object for class loading.
239 private final ConcurrentHashMap<String, Object> parallelLockMap;
240
241 // Hashtable that maps packages to certs
242 private final Map <String, Certificate[]> package2certs;
243
244 // Shared among all packages with unsigned classes
245 private static final Certificate[] nocerts = new Certificate[0];
246
247 // The classes loaded by this class loader. The only purpose of this table
248 // is to keep the classes from being GC'ed until the loader is GC'ed.
249 private final Vector<Class<?>> classes = new Vector<>();
250
251 // The "default" domain. Set as the default ProtectionDomain on newly
252 // created classes.
253 private final ProtectionDomain defaultDomain =
254 new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
255 null, this, null);
256
257 // The initiating protection domains for all classes loaded by this loader
258 private final Set<ProtectionDomain> domains;
259
260 // Invoked by the VM to record every loaded class with this loader.
261 void addClass(Class<?> c) {
262 classes.addElement(c);
263 }
264
265 // The packages defined in this class loader. Each package name is mapped
266 // to its corresponding Package object.
267 // @GuardedBy("itself")
268 private final HashMap<String, Package> packages = new HashMap<>();
269
270 private static Void checkCreateClassLoader() {
271 SecurityManager security = System.getSecurityManager();
272 if (security != null) {
273 security.checkCreateClassLoader();
274 }
275 return null;
276 }
277
278 private ClassLoader(Void unused, ClassLoader parent) {
279 this.parent = parent;
280 if (ParallelLoaders.isRegistered(this.getClass())) {
281 parallelLockMap = new ConcurrentHashMap<>();
282 package2certs = new ConcurrentHashMap<>();
283 domains =
284 Collections.synchronizedSet(new HashSet<ProtectionDomain>());
285 assertionLock = new Object();
286 } else {
287 // no finer-grained lock; lock on the classloader instance
288 parallelLockMap = null;
289 package2certs = new Hashtable<>();
290 domains = new HashSet<>();
291 assertionLock = this;
292 }
293 }
294
295 /**
296 * Creates a new class loader using the specified parent class loader for
297 * delegation.
298 *
299 * <p> If there is a security manager, its {@link
300 * SecurityManager#checkCreateClassLoader()
301 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
302 * a security exception. </p>
303 *
304 * @param parent
305 * The parent class loader
306 *
307 * @throws SecurityException
365 *
366 * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
367 * has already been loaded. </p></li>
368 *
369 * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
370 * on the parent class loader. If the parent is <tt>null</tt> the class
371 * loader built-in to the virtual machine is used, instead. </p></li>
372 *
373 * <li><p> Invoke the {@link #findClass(String)} method to find the
374 * class. </p></li>
375 *
376 * </ol>
377 *
378 * <p> If the class was found using the above steps, and the
379 * <tt>resolve</tt> flag is true, this method will then invoke the {@link
380 * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
381 *
382 * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
383 * #findClass(String)}, rather than this method. </p>
384 *
385 * <p> Unless overridden, this method synchronizes on the result of
386 * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
387 * during the entire class loading process.
388 *
389 * @param name
390 * The <a href="#name">binary name</a> of the class
391 *
392 * @param resolve
393 * If <tt>true</tt> then resolve the class
394 *
395 * @return The resulting <tt>Class</tt> object
396 *
397 * @throws ClassNotFoundException
398 * If the class could not be found
399 */
400 protected Class<?> loadClass(String name, boolean resolve)
401 throws ClassNotFoundException
402 {
403 synchronized (getClassLoadingLock(name)) {
404 // First, check if the class has already been loaded
405 Class<?> c = findLoadedClass(name);
406 if (c == null) {
407 long t0 = System.nanoTime();
408 try {
409 if (parent != null) {
410 c = parent.loadClass(name, false);
411 } else {
412 c = findBootstrapClassOrNull(name);
413 }
414 } catch (ClassNotFoundException e) {
415 // ClassNotFoundException thrown if class not found
416 // from the non-null parent class loader
417 }
418
419 if (c == null) {
420 // If still not found, then invoke findClass in order
421 // to find the class.
422 long t1 = System.nanoTime();
423 c = findClass(name);
424
425 // this is the defining class loader; record the stats
426 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
427 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
428 sun.misc.PerfCounter.getFindClasses().increment();
429 }
430 }
431 if (resolve) {
432 resolveClass(c);
433 }
434 return c;
435 }
436 }
437
438 /**
439 * Returns the lock object for class loading operations.
440 * For backward compatibility, the default implementation of this method
441 * behaves as follows. If this ClassLoader object is registered as
442 * parallel capable, the method returns a dedicated object associated
443 * with the specified class name. Otherwise, the method returns this
444 * ClassLoader object. </p>
445 *
446 * @param className
447 * The name of the to-be-loaded class
448 *
449 * @return the lock for class loading operations
450 *
451 * @throws NullPointerException
452 * If registered as parallel capable and <tt>className</tt> is null
453 *
454 * @see #loadClass(String, boolean)
455 *
456 * @since 1.7
457 */
458 protected Object getClassLoadingLock(String className) {
459 Object lock = this;
460 if (parallelLockMap != null) {
461 Object newLock = new Object();
462 lock = parallelLockMap.putIfAbsent(className, newLock);
463 if (lock == null) {
464 lock = newLock;
465 }
466 }
467 return lock;
468 }
469
470 // This method is invoked by the virtual machine to load a class.
471 private Class<?> loadClassInternal(String name)
472 throws ClassNotFoundException
473 {
474 // For backward compatibility, explicitly lock on 'this' when
475 // the current class loader is not parallel capable.
476 if (parallelLockMap == null) {
477 synchronized (this) {
478 return loadClass(name);
479 }
480 } else {
481 return loadClass(name);
482 }
483 }
484
485 // Invoked by the VM after loading class with this loader.
486 private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {
487 final SecurityManager sm = System.getSecurityManager();
488 if (sm != null) {
489 final String name = cls.getName();
490 final int i = name.lastIndexOf('.');
491 if (i != -1) {
492 AccessController.doPrivileged(new PrivilegedAction<Void>() {
493 public Void run() {
494 sm.checkPackageAccess(name.substring(0, i));
495 return null;
496 }
911
912 // true if the name is null or has the potential to be a valid binary name
913 private boolean checkName(String name) {
914 if ((name == null) || (name.length() == 0))
915 return true;
916 if ((name.indexOf('/') != -1)
917 || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
918 return false;
919 return true;
920 }
921
922 private void checkCerts(String name, CodeSource cs) {
923 int i = name.lastIndexOf('.');
924 String pname = (i == -1) ? "" : name.substring(0, i);
925
926 Certificate[] certs = null;
927 if (cs != null) {
928 certs = cs.getCertificates();
929 }
930 Certificate[] pcerts = null;
931 if (parallelLockMap == null) {
932 synchronized (this) {
933 pcerts = package2certs.get(pname);
934 if (pcerts == null) {
935 package2certs.put(pname, (certs == null? nocerts:certs));
936 }
937 }
938 } else {
939 pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).
940 putIfAbsent(pname, (certs == null? nocerts:certs));
941 }
942 if (pcerts != null && !compareCerts(pcerts, certs)) {
943 throw new SecurityException("class \""+ name +
944 "\"'s signer information does not match signer information of other classes in the same package");
945 }
946 }
947
948 /**
949 * check to make sure the certs for the new class (certs) are the same as
950 * the certs for the first class inserted in the package (pcerts)
951 */
1213 * @since 1.2
1214 */
1215 protected Enumeration<URL> findResources(String name) throws IOException {
1216 return java.util.Collections.emptyEnumeration();
1217 }
1218
1219 // index 0: java.lang.ClassLoader.class
1220 // index 1: the immediate caller of index 0.
1221 // index 2: the immediate caller of index 1.
1222 private static native Class<? extends ClassLoader> getCaller(int index);
1223
1224 /**
1225 * Registers the caller as parallel capable.</p>
1226 * The registration succeeds if and only if all of the following
1227 * conditions are met: <br>
1228 * 1. no instance of the caller has been created</p>
1229 * 2. all of the super classes (except class Object) of the caller are
1230 * registered as parallel capable</p>
1231 * Note that once a class loader is registered as parallel capable, there
1232 * is no way to change it back. </p>
1233 *
1234 * @return true if the caller is successfully registered as
1235 * parallel capable and false if otherwise.
1236 *
1237 * @since 1.7
1238 */
1239 protected static boolean registerAsParallelCapable() {
1240 return ParallelLoaders.register(getCaller(1));
1241 }
1242
1243 /**
1244 * Find a resource of the specified name from the search path used to load
1245 * classes. This method locates the resource through the system class
1246 * loader (see {@link #getSystemClassLoader()}). </p>
1247 *
1248 * @param name
1249 * The resource name
1250 *
1251 * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
1252 * resource, or <tt>null</tt> if the resource could not be found
1253 *
1254 * @since 1.1
1255 */
1256 public static URL getSystemResource(String name) {
1257 ClassLoader system = getSystemClassLoader();
1258 if (system == null) {
1259 return getBootstrapResource(name);
1260 }
|
91 * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
92 * class or resource to its parent class loader before attempting to find the
93 * class or resource itself. The virtual machine's built-in class loader,
94 * called the "bootstrap class loader", does not itself have a parent but may
95 * serve as the parent of a <tt>ClassLoader</tt> instance.
96 *
97 * <p> Class loaders that support concurrent loading of classes are known as
98 * <em>parallel capable</em> class loaders and are required to register
99 * themselves at their class initialization time by invoking the
100 * {@link
101 * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
102 * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
103 * capable by default. However, its subclasses still need to register themselves
104 * if they are parallel capable. <br>
105 * In environments in which the delegation model is not strictly
106 * hierarchical, class loaders need to be parallel capable, otherwise class
107 * loading can lead to deadlocks because the loader lock is held for the
108 * duration of the class loading process (see {@link #loadClass
109 * <tt>loadClass</tt>} methods).
110 *
111 * <p>Regular parallel capable class loaders may still need to use some form
112 * of synchronization to control concurrent load attempts of a given class.
113 * The {@link #getClassLoadingLock getClassLoadingLock} method is used to
114 * provide that object for use by {@link #loadClass loadClass}. A class loader
115 * can support fully concurrent loading of any class, in which case no
116 * synchronization need be used. Such parallel capable class loaders are
117 * required to register themselves at their class initialization time by
118 * invoking the
119 * {@link #registerAsFullyConcurrent registerAsFullyConcurrent} method.
120 * Note that the <tt>ClassLoader</tt> class is registered as fully
121 * concurrent by default. However, its subclasses still need to register
122 * themselves if they capable of fully concurrent class loading.
123 *
124 * <p> Normally, the Java virtual machine loads classes from the local file
125 * system in a platform-dependent manner. For example, on UNIX systems, the
126 * virtual machine loads classes from the directory defined by the
127 * <tt>CLASSPATH</tt> environment variable.
128 *
129 * <p> However, some classes may not originate from a file; they may originate
130 * from other sources, such as the network, or they could be constructed by an
131 * application. The method {@link #defineClass(String, byte[], int, int)
132 * <tt>defineClass</tt>} converts an array of bytes into an instance of class
133 * <tt>Class</tt>. Instances of this newly defined class can be created using
134 * {@link Class#newInstance <tt>Class.newInstance</tt>}.
135 *
136 * <p> The methods and constructors of objects created by a class loader may
137 * reference other classes. To determine the class(es) referred to, the Java
138 * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
139 * the class loader that originally created the class.
140 *
141 * <p> For example, an application could create a network class loader to
142 * download class files from a server. Sample code might look like:
143 *
189 */
190 public abstract class ClassLoader {
191
192 private static native void registerNatives();
193 static {
194 registerNatives();
195 }
196
197 // The parent class loader for delegation
198 // Note: VM hardcoded the offset of this field, thus all new fields
199 // must be added *after* it.
200 private final ClassLoader parent;
201
202 /**
203 * Encapsulates the set of parallel capable loader types.
204 */
205 private static class ParallelLoaders {
206 private ParallelLoaders() {}
207
208 // the set of parallel capable loader types
209 // - loader in the map -> parallel capable
210 // - loader maps to TRUE -> fully concurrent
211 private static final WeakHashMap<Class<? extends ClassLoader>,
212 Boolean> loaderTypes =
213 new WeakHashMap<>();
214
215 static {
216 synchronized (loaderTypes) { loaderTypes.put(ClassLoader.class, Boolean.TRUE); }
217 }
218
219 /**
220 * Registers the given class loader type as parallel capable.
221 * Returns {@code true} is successfully registered; {@code false} if
222 * loader's super class is not registered.
223 */
224 static boolean register(Class<? extends ClassLoader> c,
225 boolean fullyConcurrent) {
226 synchronized (loaderTypes) {
227 if (loaderTypes.containsKey(c.getSuperclass())) {
228 // register the class loader as parallel capable
229 // if and only if all of its super classes are.
230 // Note: given current classloading sequence, if
231 // the immediate super class is parallel capable,
232 // all the super classes higher up must be too.
233 loaderTypes.put(c, fullyConcurrent);
234 System.out.println("Registered: " + c.getName() + " as " +
235 (fullyConcurrent ? "fully concurrent " : " parallel capable") + " classloader");
236 return true;
237 } else {
238 return false;
239 }
240 }
241 }
242
243 /**
244 * Returns the value of the given loader in the parallel
245 * loader map, else null.
246 */
247 static Boolean getRegistration(Class<? extends ClassLoader> c) {
248 synchronized(loaderTypes) {
249 return loaderTypes.get(c);
250 }
251 }
252 }
253
254 // Maps class name to the corresponding lock object when the current
255 // class loader is parallel capable.
256 // Note: VM also uses this field to decide if the current class loader
257 // is parallel capable and the appropriate lock object for class loading.
258 private final ConcurrentHashMap<String, Object> parallelLockMap;
259
260 // Indicates this parallel capable loader supports fully concurrent loading
261 // Note: the VM uses this field to decide if the current class loader
262 // allows parallel class definition
263 private final boolean isFullyConcurrent;
264
265 // Indicate if this loader is parallel capable
266 private boolean isParallelCapable() {
267 return parallelLockMap != null || isFullyConcurrent;
268 }
269
270 // Hashtable that maps packages to certs
271 private final Map <String, Certificate[]> package2certs;
272
273 // Shared among all packages with unsigned classes
274 private static final Certificate[] nocerts = new Certificate[0];
275
276 // The classes loaded by this class loader. The only purpose of this table
277 // is to keep the classes from being GC'ed until the loader is GC'ed.
278 private final Vector<Class<?>> classes = new Vector<>();
279
280 // The "default" domain. Set as the default ProtectionDomain on newly
281 // created classes.
282 private final ProtectionDomain defaultDomain =
283 new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
284 null, this, null);
285
286 // The initiating protection domains for all classes loaded by this loader
287 private final Set<ProtectionDomain> domains;
288
289 // Invoked by the VM to record every loaded class with this loader.
290 void addClass(Class<?> c) {
291 classes.addElement(c);
292 }
293
294 // The packages defined in this class loader. Each package name is mapped
295 // to its corresponding Package object.
296 // @GuardedBy("itself")
297 private final HashMap<String, Package> packages = new HashMap<>();
298
299 private static Void checkCreateClassLoader() {
300 SecurityManager security = System.getSecurityManager();
301 if (security != null) {
302 security.checkCreateClassLoader();
303 }
304 return null;
305 }
306
307 private ClassLoader(Void unused, ClassLoader parent) {
308 this.parent = parent;
309 Boolean reg = ParallelLoaders.getRegistration(this.getClass());
310 if (reg != null) {
311 isFullyConcurrent = reg;
312 if (isFullyConcurrent)
313 parallelLockMap = null;
314 else
315 parallelLockMap = new ConcurrentHashMap<>();
316 package2certs = new ConcurrentHashMap<>();
317 domains =
318 Collections.synchronizedSet(new HashSet<ProtectionDomain>());
319 assertionLock = new Object();
320 } else {
321 // no finer-grained lock; lock on the classloader instance
322 isFullyConcurrent = false;
323 parallelLockMap = null;
324 package2certs = new Hashtable<>();
325 domains = new HashSet<>();
326 assertionLock = this;
327 }
328 }
329
330 /**
331 * Creates a new class loader using the specified parent class loader for
332 * delegation.
333 *
334 * <p> If there is a security manager, its {@link
335 * SecurityManager#checkCreateClassLoader()
336 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
337 * a security exception. </p>
338 *
339 * @param parent
340 * The parent class loader
341 *
342 * @throws SecurityException
400 *
401 * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
402 * has already been loaded. </p></li>
403 *
404 * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
405 * on the parent class loader. If the parent is <tt>null</tt> the class
406 * loader built-in to the virtual machine is used, instead. </p></li>
407 *
408 * <li><p> Invoke the {@link #findClass(String)} method to find the
409 * class. </p></li>
410 *
411 * </ol>
412 *
413 * <p> If the class was found using the above steps, and the
414 * <tt>resolve</tt> flag is true, this method will then invoke the {@link
415 * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
416 *
417 * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
418 * #findClass(String)}, rather than this method. </p>
419 *
420 * <p> Unless overridden, if this loader is not fully concurrent then
421 * this method synchronizes on the result
422 * of the {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
423 * during the entire class loading process. For a fully concurrent loader
424 * no synchronization occurs.
425 *
426 * @param name
427 * The <a href="#name">binary name</a> of the class
428 *
429 * @param resolve
430 * If <tt>true</tt> then resolve the class
431 *
432 * @return The resulting <tt>Class</tt> object
433 *
434 * @throws ClassNotFoundException
435 * If the class could not be found
436 */
437 protected Class<?> loadClass(String name, boolean resolve)
438 throws ClassNotFoundException
439 {
440 Class<?> c = null;
441 if (!isFullyConcurrent) {
442 synchronized (getClassLoadingLock(name)) {
443 c = do_loadClass(name);
444 if (resolve) {
445 resolveClass(c);
446 }
447 }
448 }
449 else {
450 c = do_loadClass(name);
451 if (resolve) {
452 resolveClass(c);
453 }
454 }
455 return c;
456 }
457
458
459 private Class<?> do_loadClass(String name)
460 throws ClassNotFoundException
461 {
462 // First, check if the class has already been loaded
463 Class<?> c = findLoadedClass(name);
464 if (c == null) {
465 long t0 = System.nanoTime();
466 try {
467 if (parent != null) {
468 c = parent.loadClass(name, false);
469 } else {
470 c = findBootstrapClassOrNull(name);
471 }
472 } catch (ClassNotFoundException e) {
473 // ClassNotFoundException thrown if class not found
474 // from the non-null parent class loader
475 }
476
477 if (c == null) {
478 // If still not found, then invoke findClass in order
479 // to find the class.
480 long t1 = System.nanoTime();
481 c = findClass(name);
482
483 // this is the defining class loader; record the stats
484 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
485 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
486 sun.misc.PerfCounter.getFindClasses().increment();
487 }
488 }
489 return c;
490 }
491
492 /**
493 * Returns the lock object for class loading operations.
494 * For backward compatibility, the default implementation of this method
495 * behaves as follows. If this ClassLoader object is registered as
496 * parallel capable, the method returns a dedicated object associated
497 * with the specified class name. Otherwise, the method returns this
498 * ClassLoader object. </p>
499 *
500 * @param className
501 * The name of the to-be-loaded class
502 *
503 * @return the lock for class loading operations
504 *
505 * @throws NullPointerException
506 * If registered as parallel capable and <tt>className</tt> is null
507 *
508 * @see #loadClass(String, boolean)
509 *
510 * @since 1.7
511 */
512 protected Object getClassLoadingLock(String className) {
513 Object lock = this;
514 if (parallelLockMap != null) {
515 Object newLock = new Object();
516 lock = parallelLockMap.putIfAbsent(className, newLock);
517 if (lock == null) {
518 lock = newLock;
519 }
520 }
521 else if (isFullyConcurrent) {
522 lock = null; // TBD: is this the best thing to return?
523 }
524 return lock;
525 }
526
527 // This method is invoked by the virtual machine to load a class.
528 private Class<?> loadClassInternal(String name)
529 throws ClassNotFoundException
530 {
531 // For backward compatibility, explicitly lock on 'this' when
532 // the current class loader is not parallel capable.
533 if (!isParallelCapable()) {
534 synchronized (this) {
535 return loadClass(name);
536 }
537 } else {
538 return loadClass(name);
539 }
540 }
541
542 // Invoked by the VM after loading class with this loader.
543 private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {
544 final SecurityManager sm = System.getSecurityManager();
545 if (sm != null) {
546 final String name = cls.getName();
547 final int i = name.lastIndexOf('.');
548 if (i != -1) {
549 AccessController.doPrivileged(new PrivilegedAction<Void>() {
550 public Void run() {
551 sm.checkPackageAccess(name.substring(0, i));
552 return null;
553 }
968
969 // true if the name is null or has the potential to be a valid binary name
970 private boolean checkName(String name) {
971 if ((name == null) || (name.length() == 0))
972 return true;
973 if ((name.indexOf('/') != -1)
974 || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
975 return false;
976 return true;
977 }
978
979 private void checkCerts(String name, CodeSource cs) {
980 int i = name.lastIndexOf('.');
981 String pname = (i == -1) ? "" : name.substring(0, i);
982
983 Certificate[] certs = null;
984 if (cs != null) {
985 certs = cs.getCertificates();
986 }
987 Certificate[] pcerts = null;
988 if (!isParallelCapable()) {
989 synchronized (this) {
990 pcerts = package2certs.get(pname);
991 if (pcerts == null) {
992 package2certs.put(pname, (certs == null? nocerts:certs));
993 }
994 }
995 } else {
996 pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).
997 putIfAbsent(pname, (certs == null? nocerts:certs));
998 }
999 if (pcerts != null && !compareCerts(pcerts, certs)) {
1000 throw new SecurityException("class \""+ name +
1001 "\"'s signer information does not match signer information of other classes in the same package");
1002 }
1003 }
1004
1005 /**
1006 * check to make sure the certs for the new class (certs) are the same as
1007 * the certs for the first class inserted in the package (pcerts)
1008 */
1270 * @since 1.2
1271 */
1272 protected Enumeration<URL> findResources(String name) throws IOException {
1273 return java.util.Collections.emptyEnumeration();
1274 }
1275
1276 // index 0: java.lang.ClassLoader.class
1277 // index 1: the immediate caller of index 0.
1278 // index 2: the immediate caller of index 1.
1279 private static native Class<? extends ClassLoader> getCaller(int index);
1280
1281 /**
1282 * Registers the caller as parallel capable.</p>
1283 * The registration succeeds if and only if all of the following
1284 * conditions are met: <br>
1285 * 1. no instance of the caller has been created</p>
1286 * 2. all of the super classes (except class Object) of the caller are
1287 * registered as parallel capable</p>
1288 * Note that once a class loader is registered as parallel capable, there
1289 * is no way to change it back. </p>
1290 * <p>
1291 * Class loaders that are fully concurrent parallel capable should
1292 * use {@link #registerAsFullyConcurrent} to register. </p>
1293 *
1294 * @return true if the caller is successfully registered as
1295 * parallel capable and false if otherwise.
1296 *
1297 * @since 1.7
1298 */
1299 protected static boolean registerAsParallelCapable() {
1300 return ParallelLoaders.register(getCaller(1), false);
1301 }
1302
1303 /**
1304 * Registers the caller as a fully concurrent parallel capable
1305 * class loader.</p>
1306 * The registration succeeds if and only if all of the following
1307 * conditions are met: <br>
1308 * 1. no instance of the caller has been created</p>
1309 * 2. all of the super classes (except class Object) of the caller are
1310 * registered as parallel capable</p>
1311 * Note that once a class loader is registered as fully concurrent
1312 * parallel capable, there is no way to change it back. </p>
1313 *
1314 * @return true if the caller is successfully registered as
1315 * fully concurrent parallel capable and false if otherwise.
1316 *
1317 * @since 1.8
1318 */
1319 protected static boolean registerAsFullyConcurrent() {
1320 return ParallelLoaders.register(getCaller(1), true);
1321 }
1322
1323 /**
1324 * Find a resource of the specified name from the search path used to load
1325 * classes. This method locates the resource through the system class
1326 * loader (see {@link #getSystemClassLoader()}). </p>
1327 *
1328 * @param name
1329 * The resource name
1330 *
1331 * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
1332 * resource, or <tt>null</tt> if the resource could not be found
1333 *
1334 * @since 1.1
1335 */
1336 public static URL getSystemResource(String name) {
1337 ClassLoader system = getSystemClassLoader();
1338 if (system == null) {
1339 return getBootstrapResource(name);
1340 }
|