|
1 /* |
|
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 package java.lang; |
|
26 |
|
27 import java.io.InputStream; |
|
28 import java.io.IOException; |
|
29 import java.io.File; |
|
30 import java.lang.reflect.Constructor; |
|
31 import java.lang.reflect.InvocationTargetException; |
|
32 import java.net.MalformedURLException; |
|
33 import java.net.URL; |
|
34 import java.security.AccessController; |
|
35 import java.security.AccessControlContext; |
|
36 import java.security.CodeSource; |
|
37 import java.security.Policy; |
|
38 import java.security.PrivilegedAction; |
|
39 import java.security.PrivilegedActionException; |
|
40 import java.security.PrivilegedExceptionAction; |
|
41 import java.security.ProtectionDomain; |
|
42 import java.security.cert.Certificate; |
|
43 import java.util.Collections; |
|
44 import java.util.Enumeration; |
|
45 import java.util.HashMap; |
|
46 import java.util.HashSet; |
|
47 import java.util.Set; |
|
48 import java.util.Stack; |
|
49 import java.util.Map; |
|
50 import java.util.Vector; |
|
51 import java.util.Hashtable; |
|
52 import java.util.WeakHashMap; |
|
53 import java.util.concurrent.ConcurrentHashMap; |
|
54 import sun.misc.CompoundEnumeration; |
|
55 import sun.misc.Resource; |
|
56 import sun.misc.URLClassPath; |
|
57 import sun.misc.VM; |
|
58 import sun.reflect.CallerSensitive; |
|
59 import sun.reflect.Reflection; |
|
60 import sun.reflect.misc.ReflectUtil; |
|
61 import sun.security.util.SecurityConstants; |
|
62 |
|
63 /** |
|
64 * A class loader is an object that is responsible for loading classes. The |
|
65 * class <tt>ClassLoader</tt> is an abstract class. Given the <a |
|
66 * href="#name">binary name</a> of a class, a class loader should attempt to |
|
67 * locate or generate data that constitutes a definition for the class. A |
|
68 * typical strategy is to transform the name into a file name and then read a |
|
69 * "class file" of that name from a file system. |
|
70 * |
|
71 * <p> Every {@link Class <tt>Class</tt>} object contains a {@link |
|
72 * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined |
|
73 * it. |
|
74 * |
|
75 * <p> <tt>Class</tt> objects for array classes are not created by class |
|
76 * loaders, but are created automatically as required by the Java runtime. |
|
77 * The class loader for an array class, as returned by {@link |
|
78 * Class#getClassLoader()} is the same as the class loader for its element |
|
79 * type; if the element type is a primitive type, then the array class has no |
|
80 * class loader. |
|
81 * |
|
82 * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to |
|
83 * extend the manner in which the Java virtual machine dynamically loads |
|
84 * classes. |
|
85 * |
|
86 * <p> Class loaders may typically be used by security managers to indicate |
|
87 * security domains. |
|
88 * |
|
89 * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for |
|
90 * classes and resources. Each instance of <tt>ClassLoader</tt> has an |
|
91 * associated parent class loader. When requested to find a class or |
|
92 * resource, a <tt>ClassLoader</tt> instance will delegate the search for the |
|
93 * class or resource to its parent class loader before attempting to find the |
|
94 * class or resource itself. The virtual machine's built-in class loader, |
|
95 * called the "bootstrap class loader", does not itself have a parent but may |
|
96 * serve as the parent of a <tt>ClassLoader</tt> instance. |
|
97 * |
|
98 * <p> Class loaders that support concurrent loading of classes are known as |
|
99 * <em>parallel capable</em> class loaders and are required to register |
|
100 * themselves at their class initialization time by invoking the |
|
101 * {@link |
|
102 * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>} |
|
103 * method. Note that the <tt>ClassLoader</tt> class is registered as parallel |
|
104 * capable by default. However, its subclasses still need to register themselves |
|
105 * if they are parallel capable. <br> |
|
106 * In environments in which the delegation model is not strictly |
|
107 * hierarchical, class loaders need to be parallel capable, otherwise class |
|
108 * loading can lead to deadlocks because the loader lock is held for the |
|
109 * duration of the class loading process (see {@link #loadClass |
|
110 * <tt>loadClass</tt>} methods). |
|
111 * |
|
112 * <p> Normally, the Java virtual machine loads classes from the local file |
|
113 * system in a platform-dependent manner. For example, on UNIX systems, the |
|
114 * virtual machine loads classes from the directory defined by the |
|
115 * <tt>CLASSPATH</tt> environment variable. |
|
116 * |
|
117 * <p> However, some classes may not originate from a file; they may originate |
|
118 * from other sources, such as the network, or they could be constructed by an |
|
119 * application. The method {@link #defineClass(String, byte[], int, int) |
|
120 * <tt>defineClass</tt>} converts an array of bytes into an instance of class |
|
121 * <tt>Class</tt>. Instances of this newly defined class can be created using |
|
122 * {@link Class#newInstance <tt>Class.newInstance</tt>}. |
|
123 * |
|
124 * <p> The methods and constructors of objects created by a class loader may |
|
125 * reference other classes. To determine the class(es) referred to, the Java |
|
126 * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of |
|
127 * the class loader that originally created the class. |
|
128 * |
|
129 * <p> For example, an application could create a network class loader to |
|
130 * download class files from a server. Sample code might look like: |
|
131 * |
|
132 * <blockquote><pre> |
|
133 * ClassLoader loader = new NetworkClassLoader(host, port); |
|
134 * Object main = loader.loadClass("Main", true).newInstance(); |
|
135 * . . . |
|
136 * </pre></blockquote> |
|
137 * |
|
138 * <p> The network class loader subclass must define the methods {@link |
|
139 * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class |
|
140 * from the network. Once it has downloaded the bytes that make up the class, |
|
141 * it should use the method {@link #defineClass <tt>defineClass</tt>} to |
|
142 * create a class instance. A sample implementation is: |
|
143 * |
|
144 * <blockquote><pre> |
|
145 * class NetworkClassLoader extends ClassLoader { |
|
146 * String host; |
|
147 * int port; |
|
148 * |
|
149 * public Class findClass(String name) { |
|
150 * byte[] b = loadClassData(name); |
|
151 * return defineClass(name, b, 0, b.length); |
|
152 * } |
|
153 * |
|
154 * private byte[] loadClassData(String name) { |
|
155 * // load the class data from the connection |
|
156 * . . . |
|
157 * } |
|
158 * } |
|
159 * </pre></blockquote> |
|
160 * |
|
161 * <h3> <a name="name">Binary names</a> </h3> |
|
162 * |
|
163 * <p> Any class name provided as a {@link String} parameter to methods in |
|
164 * <tt>ClassLoader</tt> must be a binary name as defined by |
|
165 * <cite>The Java™ Language Specification</cite>. |
|
166 * |
|
167 * <p> Examples of valid class names include: |
|
168 * <blockquote><pre> |
|
169 * "java.lang.String" |
|
170 * "javax.swing.JSpinner$DefaultEditor" |
|
171 * "java.security.KeyStore$Builder$FileBuilder$1" |
|
172 * "java.net.URLClassLoader$3$1" |
|
173 * </pre></blockquote> |
|
174 * |
|
175 * {@code Class} objects for array classes are not created by {@code ClassLoader}; |
|
176 * use the {@link Class#forName} method instead. |
|
177 * |
|
178 * @jls 13.1 The Form of a Binary |
|
179 * @see #resolveClass(Class) |
|
180 * @since 1.0 |
|
181 */ |
|
182 public abstract class ClassLoader { |
|
183 |
|
184 private static native void registerNatives(); |
|
185 static { |
|
186 registerNatives(); |
|
187 } |
|
188 |
|
189 // The parent class loader for delegation |
|
190 // Note: VM hardcoded the offset of this field, thus all new fields |
|
191 // must be added *after* it. |
|
192 private final ClassLoader parent; |
|
193 |
|
194 /** |
|
195 * Encapsulates the set of parallel capable loader types. |
|
196 */ |
|
197 private static class ParallelLoaders { |
|
198 private ParallelLoaders() {} |
|
199 |
|
200 // the set of parallel capable loader types |
|
201 private static final Set<Class<? extends ClassLoader>> loaderTypes = |
|
202 Collections.newSetFromMap(new WeakHashMap<>()); |
|
203 static { |
|
204 synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); } |
|
205 } |
|
206 |
|
207 /** |
|
208 * Registers the given class loader type as parallel capabale. |
|
209 * Returns {@code true} is successfully registered; {@code false} if |
|
210 * loader's super class is not registered. |
|
211 */ |
|
212 static boolean register(Class<? extends ClassLoader> c) { |
|
213 synchronized (loaderTypes) { |
|
214 if (loaderTypes.contains(c.getSuperclass())) { |
|
215 // register the class loader as parallel capable |
|
216 // if and only if all of its super classes are. |
|
217 // Note: given current classloading sequence, if |
|
218 // the immediate super class is parallel capable, |
|
219 // all the super classes higher up must be too. |
|
220 loaderTypes.add(c); |
|
221 return true; |
|
222 } else { |
|
223 return false; |
|
224 } |
|
225 } |
|
226 } |
|
227 |
|
228 /** |
|
229 * Returns {@code true} if the given class loader type is |
|
230 * registered as parallel capable. |
|
231 */ |
|
232 static boolean isRegistered(Class<? extends ClassLoader> c) { |
|
233 synchronized (loaderTypes) { |
|
234 return loaderTypes.contains(c); |
|
235 } |
|
236 } |
|
237 } |
|
238 |
|
239 // Maps class name to the corresponding lock object when the current |
|
240 // class loader is parallel capable. |
|
241 // Note: VM also uses this field to decide if the current class loader |
|
242 // is parallel capable and the appropriate lock object for class loading. |
|
243 private final ConcurrentHashMap<String, Object> parallelLockMap; |
|
244 |
|
245 // Hashtable that maps packages to certs |
|
246 private final Map <String, Certificate[]> package2certs; |
|
247 |
|
248 // Shared among all packages with unsigned classes |
|
249 private static final Certificate[] nocerts = new Certificate[0]; |
|
250 |
|
251 // The classes loaded by this class loader. The only purpose of this table |
|
252 // is to keep the classes from being GC'ed until the loader is GC'ed. |
|
253 private final Vector<Class<?>> classes = new Vector<>(); |
|
254 |
|
255 // The "default" domain. Set as the default ProtectionDomain on newly |
|
256 // created classes. |
|
257 private final ProtectionDomain defaultDomain = |
|
258 new ProtectionDomain(new CodeSource(null, (Certificate[]) null), |
|
259 null, this, null); |
|
260 |
|
261 // The initiating protection domains for all classes loaded by this loader |
|
262 private final Set<ProtectionDomain> domains; |
|
263 |
|
264 // Invoked by the VM to record every loaded class with this loader. |
|
265 void addClass(Class<?> c) { |
|
266 classes.addElement(c); |
|
267 } |
|
268 |
|
269 // The packages defined in this class loader. Each package name is mapped |
|
270 // to its corresponding Package object. |
|
271 // @GuardedBy("itself") |
|
272 private final HashMap<String, Package> packages = new HashMap<>(); |
|
273 |
|
274 private static Void checkCreateClassLoader() { |
|
275 SecurityManager security = System.getSecurityManager(); |
|
276 if (security != null) { |
|
277 security.checkCreateClassLoader(); |
|
278 } |
|
279 return null; |
|
280 } |
|
281 |
|
282 private ClassLoader(Void unused, ClassLoader parent) { |
|
283 this.parent = parent; |
|
284 if (ParallelLoaders.isRegistered(this.getClass())) { |
|
285 parallelLockMap = new ConcurrentHashMap<>(); |
|
286 package2certs = new ConcurrentHashMap<>(); |
|
287 domains = Collections.synchronizedSet(new HashSet<>()); |
|
288 assertionLock = new Object(); |
|
289 } else { |
|
290 // no finer-grained lock; lock on the classloader instance |
|
291 parallelLockMap = null; |
|
292 package2certs = new Hashtable<>(); |
|
293 domains = new HashSet<>(); |
|
294 assertionLock = this; |
|
295 } |
|
296 } |
|
297 |
|
298 /** |
|
299 * Creates a new class loader using the specified parent class loader for |
|
300 * delegation. |
|
301 * |
|
302 * <p> If there is a security manager, its {@link |
|
303 * SecurityManager#checkCreateClassLoader() |
|
304 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in |
|
305 * a security exception. </p> |
|
306 * |
|
307 * @param parent |
|
308 * The parent class loader |
|
309 * |
|
310 * @throws SecurityException |
|
311 * If a security manager exists and its |
|
312 * <tt>checkCreateClassLoader</tt> method doesn't allow creation |
|
313 * of a new class loader. |
|
314 * |
|
315 * @since 1.2 |
|
316 */ |
|
317 protected ClassLoader(ClassLoader parent) { |
|
318 this(checkCreateClassLoader(), parent); |
|
319 } |
|
320 |
|
321 /** |
|
322 * Creates a new class loader using the <tt>ClassLoader</tt> returned by |
|
323 * the method {@link #getSystemClassLoader() |
|
324 * <tt>getSystemClassLoader()</tt>} as the parent class loader. |
|
325 * |
|
326 * <p> If there is a security manager, its {@link |
|
327 * SecurityManager#checkCreateClassLoader() |
|
328 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in |
|
329 * a security exception. </p> |
|
330 * |
|
331 * @throws SecurityException |
|
332 * If a security manager exists and its |
|
333 * <tt>checkCreateClassLoader</tt> method doesn't allow creation |
|
334 * of a new class loader. |
|
335 */ |
|
336 protected ClassLoader() { |
|
337 this(checkCreateClassLoader(), getSystemClassLoader()); |
|
338 } |
|
339 |
|
340 // -- Class -- |
|
341 |
|
342 /** |
|
343 * Loads the class with the specified <a href="#name">binary name</a>. |
|
344 * This method searches for classes in the same manner as the {@link |
|
345 * #loadClass(String, boolean)} method. It is invoked by the Java virtual |
|
346 * machine to resolve class references. Invoking this method is equivalent |
|
347 * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name, |
|
348 * false)</tt>}. |
|
349 * |
|
350 * @param name |
|
351 * The <a href="#name">binary name</a> of the class |
|
352 * |
|
353 * @return The resulting <tt>Class</tt> object |
|
354 * |
|
355 * @throws ClassNotFoundException |
|
356 * If the class was not found |
|
357 */ |
|
358 public Class<?> loadClass(String name) throws ClassNotFoundException { |
|
359 return loadClass(name, false); |
|
360 } |
|
361 |
|
362 /** |
|
363 * Loads the class with the specified <a href="#name">binary name</a>. The |
|
364 * default implementation of this method searches for classes in the |
|
365 * following order: |
|
366 * |
|
367 * <ol> |
|
368 * |
|
369 * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class |
|
370 * has already been loaded. </p></li> |
|
371 * |
|
372 * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method |
|
373 * on the parent class loader. If the parent is <tt>null</tt> the class |
|
374 * loader built-in to the virtual machine is used, instead. </p></li> |
|
375 * |
|
376 * <li><p> Invoke the {@link #findClass(String)} method to find the |
|
377 * class. </p></li> |
|
378 * |
|
379 * </ol> |
|
380 * |
|
381 * <p> If the class was found using the above steps, and the |
|
382 * <tt>resolve</tt> flag is true, this method will then invoke the {@link |
|
383 * #resolveClass(Class)} method on the resulting <tt>Class</tt> object. |
|
384 * |
|
385 * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link |
|
386 * #findClass(String)}, rather than this method. </p> |
|
387 * |
|
388 * <p> Unless overridden, this method synchronizes on the result of |
|
389 * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method |
|
390 * during the entire class loading process. |
|
391 * |
|
392 * @param name |
|
393 * The <a href="#name">binary name</a> of the class |
|
394 * |
|
395 * @param resolve |
|
396 * If <tt>true</tt> then resolve the class |
|
397 * |
|
398 * @return The resulting <tt>Class</tt> object |
|
399 * |
|
400 * @throws ClassNotFoundException |
|
401 * If the class could not be found |
|
402 */ |
|
403 protected Class<?> loadClass(String name, boolean resolve) |
|
404 throws ClassNotFoundException |
|
405 { |
|
406 synchronized (getClassLoadingLock(name)) { |
|
407 // First, check if the class has already been loaded |
|
408 Class<?> c = findLoadedClass(name); |
|
409 if (c == null) { |
|
410 long t0 = System.nanoTime(); |
|
411 try { |
|
412 if (parent != null) { |
|
413 c = parent.loadClass(name, false); |
|
414 } else { |
|
415 c = findBootstrapClassOrNull(name); |
|
416 } |
|
417 } catch (ClassNotFoundException e) { |
|
418 // ClassNotFoundException thrown if class not found |
|
419 // from the non-null parent class loader |
|
420 } |
|
421 |
|
422 if (c == null) { |
|
423 // If still not found, then invoke findClass in order |
|
424 // to find the class. |
|
425 long t1 = System.nanoTime(); |
|
426 c = findClass(name); |
|
427 |
|
428 // this is the defining class loader; record the stats |
|
429 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); |
|
430 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); |
|
431 sun.misc.PerfCounter.getFindClasses().increment(); |
|
432 } |
|
433 } |
|
434 if (resolve) { |
|
435 resolveClass(c); |
|
436 } |
|
437 return c; |
|
438 } |
|
439 } |
|
440 |
|
441 /** |
|
442 * Returns the lock object for class loading operations. |
|
443 * For backward compatibility, the default implementation of this method |
|
444 * behaves as follows. If this ClassLoader object is registered as |
|
445 * parallel capable, the method returns a dedicated object associated |
|
446 * with the specified class name. Otherwise, the method returns this |
|
447 * ClassLoader object. |
|
448 * |
|
449 * @param className |
|
450 * The name of the to-be-loaded class |
|
451 * |
|
452 * @return the lock for class loading operations |
|
453 * |
|
454 * @throws NullPointerException |
|
455 * If registered as parallel capable and <tt>className</tt> is null |
|
456 * |
|
457 * @see #loadClass(String, boolean) |
|
458 * |
|
459 * @since 1.7 |
|
460 */ |
|
461 protected Object getClassLoadingLock(String className) { |
|
462 Object lock = this; |
|
463 if (parallelLockMap != null) { |
|
464 Object newLock = new Object(); |
|
465 lock = parallelLockMap.putIfAbsent(className, newLock); |
|
466 if (lock == null) { |
|
467 lock = newLock; |
|
468 } |
|
469 } |
|
470 return lock; |
|
471 } |
|
472 |
|
473 // This method is invoked by the virtual machine to load a class. |
|
474 private Class<?> loadClassInternal(String name) |
|
475 throws ClassNotFoundException |
|
476 { |
|
477 // For backward compatibility, explicitly lock on 'this' when |
|
478 // the current class loader is not parallel capable. |
|
479 if (parallelLockMap == null) { |
|
480 synchronized (this) { |
|
481 return loadClass(name); |
|
482 } |
|
483 } else { |
|
484 return loadClass(name); |
|
485 } |
|
486 } |
|
487 |
|
488 // Invoked by the VM after loading class with this loader. |
|
489 private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) { |
|
490 final SecurityManager sm = System.getSecurityManager(); |
|
491 if (sm != null) { |
|
492 if (ReflectUtil.isNonPublicProxyClass(cls)) { |
|
493 for (Class<?> intf: cls.getInterfaces()) { |
|
494 checkPackageAccess(intf, pd); |
|
495 } |
|
496 return; |
|
497 } |
|
498 |
|
499 final String name = cls.getName(); |
|
500 final int i = name.lastIndexOf('.'); |
|
501 if (i != -1) { |
|
502 AccessController.doPrivileged(new PrivilegedAction<Void>() { |
|
503 public Void run() { |
|
504 sm.checkPackageAccess(name.substring(0, i)); |
|
505 return null; |
|
506 } |
|
507 }, new AccessControlContext(new ProtectionDomain[] {pd})); |
|
508 } |
|
509 } |
|
510 domains.add(pd); |
|
511 } |
|
512 |
|
513 /** |
|
514 * Finds the class with the specified <a href="#name">binary name</a>. |
|
515 * This method should be overridden by class loader implementations that |
|
516 * follow the delegation model for loading classes, and will be invoked by |
|
517 * the {@link #loadClass <tt>loadClass</tt>} method after checking the |
|
518 * parent class loader for the requested class. The default implementation |
|
519 * throws a <tt>ClassNotFoundException</tt>. |
|
520 * |
|
521 * @param name |
|
522 * The <a href="#name">binary name</a> of the class |
|
523 * |
|
524 * @return The resulting <tt>Class</tt> object |
|
525 * |
|
526 * @throws ClassNotFoundException |
|
527 * If the class could not be found |
|
528 * |
|
529 * @since 1.2 |
|
530 */ |
|
531 protected Class<?> findClass(String name) throws ClassNotFoundException { |
|
532 throw new ClassNotFoundException(name); |
|
533 } |
|
534 |
|
535 /** |
|
536 * Converts an array of bytes into an instance of class <tt>Class</tt>. |
|
537 * Before the <tt>Class</tt> can be used it must be resolved. This method |
|
538 * is deprecated in favor of the version that takes a <a |
|
539 * href="#name">binary name</a> as its first argument, and is more secure. |
|
540 * |
|
541 * @param b |
|
542 * The bytes that make up the class data. The bytes in positions |
|
543 * <tt>off</tt> through <tt>off+len-1</tt> should have the format |
|
544 * of a valid class file as defined by |
|
545 * <cite>The Java™ Virtual Machine Specification</cite>. |
|
546 * |
|
547 * @param off |
|
548 * The start offset in <tt>b</tt> of the class data |
|
549 * |
|
550 * @param len |
|
551 * The length of the class data |
|
552 * |
|
553 * @return The <tt>Class</tt> object that was created from the specified |
|
554 * class data |
|
555 * |
|
556 * @throws ClassFormatError |
|
557 * If the data did not contain a valid class |
|
558 * |
|
559 * @throws IndexOutOfBoundsException |
|
560 * If either <tt>off</tt> or <tt>len</tt> is negative, or if |
|
561 * <tt>off+len</tt> is greater than <tt>b.length</tt>. |
|
562 * |
|
563 * @throws SecurityException |
|
564 * If an attempt is made to add this class to a package that |
|
565 * contains classes that were signed by a different set of |
|
566 * certificates than this class, or if an attempt is made |
|
567 * to define a class in a package with a fully-qualified name |
|
568 * that starts with "{@code java.}". |
|
569 * |
|
570 * @see #loadClass(String, boolean) |
|
571 * @see #resolveClass(Class) |
|
572 * |
|
573 * @deprecated Replaced by {@link #defineClass(String, byte[], int, int) |
|
574 * defineClass(String, byte[], int, int)} |
|
575 */ |
|
576 @Deprecated |
|
577 protected final Class<?> defineClass(byte[] b, int off, int len) |
|
578 throws ClassFormatError |
|
579 { |
|
580 return defineClass(null, b, off, len, null); |
|
581 } |
|
582 |
|
583 /** |
|
584 * Converts an array of bytes into an instance of class <tt>Class</tt>. |
|
585 * Before the <tt>Class</tt> can be used it must be resolved. |
|
586 * |
|
587 * <p> This method assigns a default {@link java.security.ProtectionDomain |
|
588 * <tt>ProtectionDomain</tt>} to the newly defined class. The |
|
589 * <tt>ProtectionDomain</tt> is effectively granted the same set of |
|
590 * permissions returned when {@link |
|
591 * java.security.Policy#getPermissions(java.security.CodeSource) |
|
592 * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>} |
|
593 * is invoked. The default domain is created on the first invocation of |
|
594 * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>}, |
|
595 * and re-used on subsequent invocations. |
|
596 * |
|
597 * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use |
|
598 * the {@link #defineClass(String, byte[], int, int, |
|
599 * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a |
|
600 * <tt>ProtectionDomain</tt> as one of its arguments. </p> |
|
601 * |
|
602 * @param name |
|
603 * The expected <a href="#name">binary name</a> of the class, or |
|
604 * <tt>null</tt> if not known |
|
605 * |
|
606 * @param b |
|
607 * The bytes that make up the class data. The bytes in positions |
|
608 * <tt>off</tt> through <tt>off+len-1</tt> should have the format |
|
609 * of a valid class file as defined by |
|
610 * <cite>The Java™ Virtual Machine Specification</cite>. |
|
611 * |
|
612 * @param off |
|
613 * The start offset in <tt>b</tt> of the class data |
|
614 * |
|
615 * @param len |
|
616 * The length of the class data |
|
617 * |
|
618 * @return The <tt>Class</tt> object that was created from the specified |
|
619 * class data. |
|
620 * |
|
621 * @throws ClassFormatError |
|
622 * If the data did not contain a valid class |
|
623 * |
|
624 * @throws IndexOutOfBoundsException |
|
625 * If either <tt>off</tt> or <tt>len</tt> is negative, or if |
|
626 * <tt>off+len</tt> is greater than <tt>b.length</tt>. |
|
627 * |
|
628 * @throws SecurityException |
|
629 * If an attempt is made to add this class to a package that |
|
630 * contains classes that were signed by a different set of |
|
631 * certificates than this class (which is unsigned), or if |
|
632 * <tt>name</tt> begins with "<tt>java.</tt>". |
|
633 * |
|
634 * @see #loadClass(String, boolean) |
|
635 * @see #resolveClass(Class) |
|
636 * @see java.security.CodeSource |
|
637 * @see java.security.SecureClassLoader |
|
638 * |
|
639 * @since 1.1 |
|
640 */ |
|
641 protected final Class<?> defineClass(String name, byte[] b, int off, int len) |
|
642 throws ClassFormatError |
|
643 { |
|
644 return defineClass(name, b, off, len, null); |
|
645 } |
|
646 |
|
647 /* Determine protection domain, and check that: |
|
648 - not define java.* class, |
|
649 - signer of this class matches signers for the rest of the classes in |
|
650 package. |
|
651 */ |
|
652 private ProtectionDomain preDefineClass(String name, |
|
653 ProtectionDomain pd) |
|
654 { |
|
655 if (!checkName(name)) |
|
656 throw new NoClassDefFoundError("IllegalName: " + name); |
|
657 |
|
658 if ((name != null) && name.startsWith("java.")) { |
|
659 throw new SecurityException |
|
660 ("Prohibited package name: " + |
|
661 name.substring(0, name.lastIndexOf('.'))); |
|
662 } |
|
663 if (pd == null) { |
|
664 pd = defaultDomain; |
|
665 } |
|
666 |
|
667 if (name != null) checkCerts(name, pd.getCodeSource()); |
|
668 |
|
669 return pd; |
|
670 } |
|
671 |
|
672 private String defineClassSourceLocation(ProtectionDomain pd) |
|
673 { |
|
674 CodeSource cs = pd.getCodeSource(); |
|
675 String source = null; |
|
676 if (cs != null && cs.getLocation() != null) { |
|
677 source = cs.getLocation().toString(); |
|
678 } |
|
679 return source; |
|
680 } |
|
681 |
|
682 private void postDefineClass(Class<?> c, ProtectionDomain pd) |
|
683 { |
|
684 if (pd.getCodeSource() != null) { |
|
685 Certificate certs[] = pd.getCodeSource().getCertificates(); |
|
686 if (certs != null) |
|
687 setSigners(c, certs); |
|
688 } |
|
689 } |
|
690 |
|
691 /** |
|
692 * Converts an array of bytes into an instance of class <tt>Class</tt>, |
|
693 * with an optional <tt>ProtectionDomain</tt>. If the domain is |
|
694 * <tt>null</tt>, then a default domain will be assigned to the class as |
|
695 * specified in the documentation for {@link #defineClass(String, byte[], |
|
696 * int, int)}. Before the class can be used it must be resolved. |
|
697 * |
|
698 * <p> The first class defined in a package determines the exact set of |
|
699 * certificates that all subsequent classes defined in that package must |
|
700 * contain. The set of certificates for a class is obtained from the |
|
701 * {@link java.security.CodeSource <tt>CodeSource</tt>} within the |
|
702 * <tt>ProtectionDomain</tt> of the class. Any classes added to that |
|
703 * package must contain the same set of certificates or a |
|
704 * <tt>SecurityException</tt> will be thrown. Note that if |
|
705 * <tt>name</tt> is <tt>null</tt>, this check is not performed. |
|
706 * You should always pass in the <a href="#name">binary name</a> of the |
|
707 * class you are defining as well as the bytes. This ensures that the |
|
708 * class you are defining is indeed the class you think it is. |
|
709 * |
|
710 * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since |
|
711 * all classes in the "<tt>java.*</tt> packages can only be defined by the |
|
712 * bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it |
|
713 * must be equal to the <a href="#name">binary name</a> of the class |
|
714 * specified by the byte array "<tt>b</tt>", otherwise a {@link |
|
715 * NoClassDefFoundError <tt>NoClassDefFoundError</tt>} will be thrown. </p> |
|
716 * |
|
717 * @param name |
|
718 * The expected <a href="#name">binary name</a> of the class, or |
|
719 * <tt>null</tt> if not known |
|
720 * |
|
721 * @param b |
|
722 * The bytes that make up the class data. The bytes in positions |
|
723 * <tt>off</tt> through <tt>off+len-1</tt> should have the format |
|
724 * of a valid class file as defined by |
|
725 * <cite>The Java™ Virtual Machine Specification</cite>. |
|
726 * |
|
727 * @param off |
|
728 * The start offset in <tt>b</tt> of the class data |
|
729 * |
|
730 * @param len |
|
731 * The length of the class data |
|
732 * |
|
733 * @param protectionDomain |
|
734 * The ProtectionDomain of the class |
|
735 * |
|
736 * @return The <tt>Class</tt> object created from the data, |
|
737 * and optional <tt>ProtectionDomain</tt>. |
|
738 * |
|
739 * @throws ClassFormatError |
|
740 * If the data did not contain a valid class |
|
741 * |
|
742 * @throws NoClassDefFoundError |
|
743 * If <tt>name</tt> is not equal to the <a href="#name">binary |
|
744 * name</a> of the class specified by <tt>b</tt> |
|
745 * |
|
746 * @throws IndexOutOfBoundsException |
|
747 * If either <tt>off</tt> or <tt>len</tt> is negative, or if |
|
748 * <tt>off+len</tt> is greater than <tt>b.length</tt>. |
|
749 * |
|
750 * @throws SecurityException |
|
751 * If an attempt is made to add this class to a package that |
|
752 * contains classes that were signed by a different set of |
|
753 * certificates than this class, or if <tt>name</tt> begins with |
|
754 * "<tt>java.</tt>". |
|
755 */ |
|
756 protected final Class<?> defineClass(String name, byte[] b, int off, int len, |
|
757 ProtectionDomain protectionDomain) |
|
758 throws ClassFormatError |
|
759 { |
|
760 protectionDomain = preDefineClass(name, protectionDomain); |
|
761 String source = defineClassSourceLocation(protectionDomain); |
|
762 Class<?> c = defineClass1(name, b, off, len, protectionDomain, source); |
|
763 postDefineClass(c, protectionDomain); |
|
764 return c; |
|
765 } |
|
766 |
|
767 /** |
|
768 * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>} |
|
769 * into an instance of class <tt>Class</tt>, |
|
770 * with an optional <tt>ProtectionDomain</tt>. If the domain is |
|
771 * <tt>null</tt>, then a default domain will be assigned to the class as |
|
772 * specified in the documentation for {@link #defineClass(String, byte[], |
|
773 * int, int)}. Before the class can be used it must be resolved. |
|
774 * |
|
775 * <p>The rules about the first class defined in a package determining the |
|
776 * set of certificates for the package, and the restrictions on class names |
|
777 * are identical to those specified in the documentation for {@link |
|
778 * #defineClass(String, byte[], int, int, ProtectionDomain)}. |
|
779 * |
|
780 * <p> An invocation of this method of the form |
|
781 * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt> |
|
782 * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same |
|
783 * result as the statements |
|
784 * |
|
785 *<p> <tt> |
|
786 * ...<br> |
|
787 * byte[] temp = new byte[bBuffer.{@link |
|
788 * java.nio.ByteBuffer#remaining remaining}()];<br> |
|
789 * bBuffer.{@link java.nio.ByteBuffer#get(byte[]) |
|
790 * get}(temp);<br> |
|
791 * return {@link #defineClass(String, byte[], int, int, ProtectionDomain) |
|
792 * cl.defineClass}(name, temp, 0, |
|
793 * temp.length, pd);<br> |
|
794 * </tt></p> |
|
795 * |
|
796 * @param name |
|
797 * The expected <a href="#name">binary name</a>. of the class, or |
|
798 * <tt>null</tt> if not known |
|
799 * |
|
800 * @param b |
|
801 * The bytes that make up the class data. The bytes from positions |
|
802 * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1 |
|
803 * </tt> should have the format of a valid class file as defined by |
|
804 * <cite>The Java™ Virtual Machine Specification</cite>. |
|
805 * |
|
806 * @param protectionDomain |
|
807 * The ProtectionDomain of the class, or <tt>null</tt>. |
|
808 * |
|
809 * @return The <tt>Class</tt> object created from the data, |
|
810 * and optional <tt>ProtectionDomain</tt>. |
|
811 * |
|
812 * @throws ClassFormatError |
|
813 * If the data did not contain a valid class. |
|
814 * |
|
815 * @throws NoClassDefFoundError |
|
816 * If <tt>name</tt> is not equal to the <a href="#name">binary |
|
817 * name</a> of the class specified by <tt>b</tt> |
|
818 * |
|
819 * @throws SecurityException |
|
820 * If an attempt is made to add this class to a package that |
|
821 * contains classes that were signed by a different set of |
|
822 * certificates than this class, or if <tt>name</tt> begins with |
|
823 * "<tt>java.</tt>". |
|
824 * |
|
825 * @see #defineClass(String, byte[], int, int, ProtectionDomain) |
|
826 * |
|
827 * @since 1.5 |
|
828 */ |
|
829 protected final Class<?> defineClass(String name, java.nio.ByteBuffer b, |
|
830 ProtectionDomain protectionDomain) |
|
831 throws ClassFormatError |
|
832 { |
|
833 int len = b.remaining(); |
|
834 |
|
835 // Use byte[] if not a direct ByteBufer: |
|
836 if (!b.isDirect()) { |
|
837 if (b.hasArray()) { |
|
838 return defineClass(name, b.array(), |
|
839 b.position() + b.arrayOffset(), len, |
|
840 protectionDomain); |
|
841 } else { |
|
842 // no array, or read-only array |
|
843 byte[] tb = new byte[len]; |
|
844 b.get(tb); // get bytes out of byte buffer. |
|
845 return defineClass(name, tb, 0, len, protectionDomain); |
|
846 } |
|
847 } |
|
848 |
|
849 protectionDomain = preDefineClass(name, protectionDomain); |
|
850 String source = defineClassSourceLocation(protectionDomain); |
|
851 Class<?> c = defineClass2(name, b, b.position(), len, protectionDomain, source); |
|
852 postDefineClass(c, protectionDomain); |
|
853 return c; |
|
854 } |
|
855 |
|
856 private native Class<?> defineClass1(String name, byte[] b, int off, int len, |
|
857 ProtectionDomain pd, String source); |
|
858 |
|
859 private native Class<?> defineClass2(String name, java.nio.ByteBuffer b, |
|
860 int off, int len, ProtectionDomain pd, |
|
861 String source); |
|
862 |
|
863 // true if the name is null or has the potential to be a valid binary name |
|
864 private boolean checkName(String name) { |
|
865 if ((name == null) || (name.length() == 0)) |
|
866 return true; |
|
867 if ((name.indexOf('/') != -1) || (name.charAt(0) == '[')) |
|
868 return false; |
|
869 return true; |
|
870 } |
|
871 |
|
872 private void checkCerts(String name, CodeSource cs) { |
|
873 int i = name.lastIndexOf('.'); |
|
874 String pname = (i == -1) ? "" : name.substring(0, i); |
|
875 |
|
876 Certificate[] certs = null; |
|
877 if (cs != null) { |
|
878 certs = cs.getCertificates(); |
|
879 } |
|
880 Certificate[] pcerts = null; |
|
881 if (parallelLockMap == null) { |
|
882 synchronized (this) { |
|
883 pcerts = package2certs.get(pname); |
|
884 if (pcerts == null) { |
|
885 package2certs.put(pname, (certs == null? nocerts:certs)); |
|
886 } |
|
887 } |
|
888 } else { |
|
889 pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs). |
|
890 putIfAbsent(pname, (certs == null? nocerts:certs)); |
|
891 } |
|
892 if (pcerts != null && !compareCerts(pcerts, certs)) { |
|
893 throw new SecurityException("class \""+ name + |
|
894 "\"'s signer information does not match signer information of other classes in the same package"); |
|
895 } |
|
896 } |
|
897 |
|
898 /** |
|
899 * check to make sure the certs for the new class (certs) are the same as |
|
900 * the certs for the first class inserted in the package (pcerts) |
|
901 */ |
|
902 private boolean compareCerts(Certificate[] pcerts, |
|
903 Certificate[] certs) |
|
904 { |
|
905 // certs can be null, indicating no certs. |
|
906 if ((certs == null) || (certs.length == 0)) { |
|
907 return pcerts.length == 0; |
|
908 } |
|
909 |
|
910 // the length must be the same at this point |
|
911 if (certs.length != pcerts.length) |
|
912 return false; |
|
913 |
|
914 // go through and make sure all the certs in one array |
|
915 // are in the other and vice-versa. |
|
916 boolean match; |
|
917 for (Certificate cert : certs) { |
|
918 match = false; |
|
919 for (Certificate pcert : pcerts) { |
|
920 if (cert.equals(pcert)) { |
|
921 match = true; |
|
922 break; |
|
923 } |
|
924 } |
|
925 if (!match) return false; |
|
926 } |
|
927 |
|
928 // now do the same for pcerts |
|
929 for (Certificate pcert : pcerts) { |
|
930 match = false; |
|
931 for (Certificate cert : certs) { |
|
932 if (pcert.equals(cert)) { |
|
933 match = true; |
|
934 break; |
|
935 } |
|
936 } |
|
937 if (!match) return false; |
|
938 } |
|
939 |
|
940 return true; |
|
941 } |
|
942 |
|
943 /** |
|
944 * Links the specified class. This (misleadingly named) method may be |
|
945 * used by a class loader to link a class. If the class <tt>c</tt> has |
|
946 * already been linked, then this method simply returns. Otherwise, the |
|
947 * class is linked as described in the "Execution" chapter of |
|
948 * <cite>The Java™ Language Specification</cite>. |
|
949 * |
|
950 * @param c |
|
951 * The class to link |
|
952 * |
|
953 * @throws NullPointerException |
|
954 * If <tt>c</tt> is <tt>null</tt>. |
|
955 * |
|
956 * @see #defineClass(String, byte[], int, int) |
|
957 */ |
|
958 protected final void resolveClass(Class<?> c) { |
|
959 resolveClass0(c); |
|
960 } |
|
961 |
|
962 private native void resolveClass0(Class<?> c); |
|
963 |
|
964 /** |
|
965 * Finds a class with the specified <a href="#name">binary name</a>, |
|
966 * loading it if necessary. |
|
967 * |
|
968 * <p> This method loads the class through the system class loader (see |
|
969 * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned |
|
970 * might have more than one <tt>ClassLoader</tt> associated with it. |
|
971 * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method, |
|
972 * because most class loaders need to override just {@link |
|
973 * #findClass(String)}. </p> |
|
974 * |
|
975 * @param name |
|
976 * The <a href="#name">binary name</a> of the class |
|
977 * |
|
978 * @return The <tt>Class</tt> object for the specified <tt>name</tt> |
|
979 * |
|
980 * @throws ClassNotFoundException |
|
981 * If the class could not be found |
|
982 * |
|
983 * @see #ClassLoader(ClassLoader) |
|
984 * @see #getParent() |
|
985 */ |
|
986 protected final Class<?> findSystemClass(String name) |
|
987 throws ClassNotFoundException |
|
988 { |
|
989 ClassLoader system = getSystemClassLoader(); |
|
990 if (system == null) { |
|
991 if (!checkName(name)) |
|
992 throw new ClassNotFoundException(name); |
|
993 Class<?> cls = findBootstrapClass(name); |
|
994 if (cls == null) { |
|
995 throw new ClassNotFoundException(name); |
|
996 } |
|
997 return cls; |
|
998 } |
|
999 return system.loadClass(name); |
|
1000 } |
|
1001 |
|
1002 /** |
|
1003 * Returns a class loaded by the bootstrap class loader; |
|
1004 * or return null if not found. |
|
1005 */ |
|
1006 private Class<?> findBootstrapClassOrNull(String name) |
|
1007 { |
|
1008 if (!checkName(name)) return null; |
|
1009 |
|
1010 return findBootstrapClass(name); |
|
1011 } |
|
1012 |
|
1013 // return null if not found |
|
1014 private native Class<?> findBootstrapClass(String name); |
|
1015 |
|
1016 /** |
|
1017 * Returns the class with the given <a href="#name">binary name</a> if this |
|
1018 * loader has been recorded by the Java virtual machine as an initiating |
|
1019 * loader of a class with that <a href="#name">binary name</a>. Otherwise |
|
1020 * <tt>null</tt> is returned. |
|
1021 * |
|
1022 * @param name |
|
1023 * The <a href="#name">binary name</a> of the class |
|
1024 * |
|
1025 * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has |
|
1026 * not been loaded |
|
1027 * |
|
1028 * @since 1.1 |
|
1029 */ |
|
1030 protected final Class<?> findLoadedClass(String name) { |
|
1031 if (!checkName(name)) |
|
1032 return null; |
|
1033 return findLoadedClass0(name); |
|
1034 } |
|
1035 |
|
1036 private native final Class<?> findLoadedClass0(String name); |
|
1037 |
|
1038 /** |
|
1039 * Sets the signers of a class. This should be invoked after defining a |
|
1040 * class. |
|
1041 * |
|
1042 * @param c |
|
1043 * The <tt>Class</tt> object |
|
1044 * |
|
1045 * @param signers |
|
1046 * The signers for the class |
|
1047 * |
|
1048 * @since 1.1 |
|
1049 */ |
|
1050 protected final void setSigners(Class<?> c, Object[] signers) { |
|
1051 c.setSigners(signers); |
|
1052 } |
|
1053 |
|
1054 |
|
1055 // -- Resource -- |
|
1056 |
|
1057 /** |
|
1058 * Finds the resource with the given name. A resource is some data |
|
1059 * (images, audio, text, etc) that can be accessed by class code in a way |
|
1060 * that is independent of the location of the code. |
|
1061 * |
|
1062 * <p> The name of a resource is a '<tt>/</tt>'-separated path name that |
|
1063 * identifies the resource. |
|
1064 * |
|
1065 * <p> This method will first search the parent class loader for the |
|
1066 * resource; if the parent is <tt>null</tt> the path of the class loader |
|
1067 * built-in to the virtual machine is searched. That failing, this method |
|
1068 * will invoke {@link #findResource(String)} to find the resource. </p> |
|
1069 * |
|
1070 * @apiNote When overriding this method it is recommended that an |
|
1071 * implementation ensures that any delegation is consistent with the {@link |
|
1072 * #getResources(java.lang.String) getResources(String)} method. |
|
1073 * |
|
1074 * @param name |
|
1075 * The resource name |
|
1076 * |
|
1077 * @return A <tt>URL</tt> object for reading the resource, or |
|
1078 * <tt>null</tt> if the resource could not be found or the invoker |
|
1079 * doesn't have adequate privileges to get the resource. |
|
1080 * |
|
1081 * @since 1.1 |
|
1082 */ |
|
1083 public URL getResource(String name) { |
|
1084 URL url; |
|
1085 if (parent != null) { |
|
1086 url = parent.getResource(name); |
|
1087 } else { |
|
1088 url = getBootstrapResource(name); |
|
1089 } |
|
1090 if (url == null) { |
|
1091 url = findResource(name); |
|
1092 } |
|
1093 return url; |
|
1094 } |
|
1095 |
|
1096 /** |
|
1097 * Finds all the resources with the given name. A resource is some data |
|
1098 * (images, audio, text, etc) that can be accessed by class code in a way |
|
1099 * that is independent of the location of the code. |
|
1100 * |
|
1101 * <p>The name of a resource is a <tt>/</tt>-separated path name that |
|
1102 * identifies the resource. |
|
1103 * |
|
1104 * <p> The search order is described in the documentation for {@link |
|
1105 * #getResource(String)}. </p> |
|
1106 * |
|
1107 * @apiNote When overriding this method it is recommended that an |
|
1108 * implementation ensures that any delegation is consistent with the {@link |
|
1109 * #getResource(java.lang.String) getResource(String)} method. This should |
|
1110 * ensure that the first element returned by the Enumeration's |
|
1111 * {@code nextElement} method is the same resource that the |
|
1112 * {@code getResource(String)} method would return. |
|
1113 * |
|
1114 * @param name |
|
1115 * The resource name |
|
1116 * |
|
1117 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for |
|
1118 * the resource. If no resources could be found, the enumeration |
|
1119 * will be empty. Resources that the class loader doesn't have |
|
1120 * access to will not be in the enumeration. |
|
1121 * |
|
1122 * @throws IOException |
|
1123 * If I/O errors occur |
|
1124 * |
|
1125 * @see #findResources(String) |
|
1126 * |
|
1127 * @since 1.2 |
|
1128 */ |
|
1129 public Enumeration<URL> getResources(String name) throws IOException { |
|
1130 @SuppressWarnings("unchecked") |
|
1131 Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2]; |
|
1132 if (parent != null) { |
|
1133 tmp[0] = parent.getResources(name); |
|
1134 } else { |
|
1135 tmp[0] = getBootstrapResources(name); |
|
1136 } |
|
1137 tmp[1] = findResources(name); |
|
1138 |
|
1139 return new CompoundEnumeration<>(tmp); |
|
1140 } |
|
1141 |
|
1142 /** |
|
1143 * Finds the resource with the given name. Class loader implementations |
|
1144 * should override this method to specify where to find resources. |
|
1145 * |
|
1146 * @param name |
|
1147 * The resource name |
|
1148 * |
|
1149 * @return A <tt>URL</tt> object for reading the resource, or |
|
1150 * <tt>null</tt> if the resource could not be found |
|
1151 * |
|
1152 * @since 1.2 |
|
1153 */ |
|
1154 protected URL findResource(String name) { |
|
1155 return null; |
|
1156 } |
|
1157 |
|
1158 /** |
|
1159 * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects |
|
1160 * representing all the resources with the given name. Class loader |
|
1161 * implementations should override this method to specify where to load |
|
1162 * resources from. |
|
1163 * |
|
1164 * @param name |
|
1165 * The resource name |
|
1166 * |
|
1167 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for |
|
1168 * the resources |
|
1169 * |
|
1170 * @throws IOException |
|
1171 * If I/O errors occur |
|
1172 * |
|
1173 * @since 1.2 |
|
1174 */ |
|
1175 protected Enumeration<URL> findResources(String name) throws IOException { |
|
1176 return java.util.Collections.emptyEnumeration(); |
|
1177 } |
|
1178 |
|
1179 /** |
|
1180 * Registers the caller as parallel capable. |
|
1181 * The registration succeeds if and only if all of the following |
|
1182 * conditions are met: |
|
1183 * <ol> |
|
1184 * <li> no instance of the caller has been created</li> |
|
1185 * <li> all of the super classes (except class Object) of the caller are |
|
1186 * registered as parallel capable</li> |
|
1187 * </ol> |
|
1188 * <p>Note that once a class loader is registered as parallel capable, there |
|
1189 * is no way to change it back.</p> |
|
1190 * |
|
1191 * @return true if the caller is successfully registered as |
|
1192 * parallel capable and false if otherwise. |
|
1193 * |
|
1194 * @since 1.7 |
|
1195 */ |
|
1196 @CallerSensitive |
|
1197 protected static boolean registerAsParallelCapable() { |
|
1198 Class<? extends ClassLoader> callerClass = |
|
1199 Reflection.getCallerClass().asSubclass(ClassLoader.class); |
|
1200 return ParallelLoaders.register(callerClass); |
|
1201 } |
|
1202 |
|
1203 /** |
|
1204 * Find a resource of the specified name from the search path used to load |
|
1205 * classes. This method locates the resource through the system class |
|
1206 * loader (see {@link #getSystemClassLoader()}). |
|
1207 * |
|
1208 * @param name |
|
1209 * The resource name |
|
1210 * |
|
1211 * @return A {@link java.net.URL <tt>URL</tt>} object for reading the |
|
1212 * resource, or <tt>null</tt> if the resource could not be found |
|
1213 * |
|
1214 * @since 1.1 |
|
1215 */ |
|
1216 public static URL getSystemResource(String name) { |
|
1217 ClassLoader system = getSystemClassLoader(); |
|
1218 if (system == null) { |
|
1219 return getBootstrapResource(name); |
|
1220 } |
|
1221 return system.getResource(name); |
|
1222 } |
|
1223 |
|
1224 /** |
|
1225 * Finds all resources of the specified name from the search path used to |
|
1226 * load classes. The resources thus found are returned as an |
|
1227 * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link |
|
1228 * java.net.URL <tt>URL</tt>} objects. |
|
1229 * |
|
1230 * <p> The search order is described in the documentation for {@link |
|
1231 * #getSystemResource(String)}. </p> |
|
1232 * |
|
1233 * @param name |
|
1234 * The resource name |
|
1235 * |
|
1236 * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>} |
|
1237 * objects |
|
1238 * |
|
1239 * @throws IOException |
|
1240 * If I/O errors occur |
|
1241 |
|
1242 * @since 1.2 |
|
1243 */ |
|
1244 public static Enumeration<URL> getSystemResources(String name) |
|
1245 throws IOException |
|
1246 { |
|
1247 ClassLoader system = getSystemClassLoader(); |
|
1248 if (system == null) { |
|
1249 return getBootstrapResources(name); |
|
1250 } |
|
1251 return system.getResources(name); |
|
1252 } |
|
1253 |
|
1254 /** |
|
1255 * Find resources from the VM's built-in classloader. |
|
1256 */ |
|
1257 private static URL getBootstrapResource(String name) { |
|
1258 URLClassPath ucp = getBootstrapClassPath(); |
|
1259 Resource res = ucp.getResource(name); |
|
1260 return res != null ? res.getURL() : null; |
|
1261 } |
|
1262 |
|
1263 /** |
|
1264 * Find resources from the VM's built-in classloader. |
|
1265 */ |
|
1266 private static Enumeration<URL> getBootstrapResources(String name) |
|
1267 throws IOException |
|
1268 { |
|
1269 final Enumeration<Resource> e = |
|
1270 getBootstrapClassPath().getResources(name); |
|
1271 return new Enumeration<URL> () { |
|
1272 public URL nextElement() { |
|
1273 return e.nextElement().getURL(); |
|
1274 } |
|
1275 public boolean hasMoreElements() { |
|
1276 return e.hasMoreElements(); |
|
1277 } |
|
1278 }; |
|
1279 } |
|
1280 |
|
1281 // Returns the URLClassPath that is used for finding system resources. |
|
1282 static URLClassPath getBootstrapClassPath() { |
|
1283 return sun.misc.Launcher.getBootstrapClassPath(); |
|
1284 } |
|
1285 |
|
1286 |
|
1287 /** |
|
1288 * Returns an input stream for reading the specified resource. |
|
1289 * |
|
1290 * <p> The search order is described in the documentation for {@link |
|
1291 * #getResource(String)}. </p> |
|
1292 * |
|
1293 * @param name |
|
1294 * The resource name |
|
1295 * |
|
1296 * @return An input stream for reading the resource, or <tt>null</tt> |
|
1297 * if the resource could not be found |
|
1298 * |
|
1299 * @since 1.1 |
|
1300 */ |
|
1301 public InputStream getResourceAsStream(String name) { |
|
1302 URL url = getResource(name); |
|
1303 try { |
|
1304 return url != null ? url.openStream() : null; |
|
1305 } catch (IOException e) { |
|
1306 return null; |
|
1307 } |
|
1308 } |
|
1309 |
|
1310 /** |
|
1311 * Open for reading, a resource of the specified name from the search path |
|
1312 * used to load classes. This method locates the resource through the |
|
1313 * system class loader (see {@link #getSystemClassLoader()}). |
|
1314 * |
|
1315 * @param name |
|
1316 * The resource name |
|
1317 * |
|
1318 * @return An input stream for reading the resource, or <tt>null</tt> |
|
1319 * if the resource could not be found |
|
1320 * |
|
1321 * @since 1.1 |
|
1322 */ |
|
1323 public static InputStream getSystemResourceAsStream(String name) { |
|
1324 URL url = getSystemResource(name); |
|
1325 try { |
|
1326 return url != null ? url.openStream() : null; |
|
1327 } catch (IOException e) { |
|
1328 return null; |
|
1329 } |
|
1330 } |
|
1331 |
|
1332 |
|
1333 // -- Hierarchy -- |
|
1334 |
|
1335 /** |
|
1336 * Returns the parent class loader for delegation. Some implementations may |
|
1337 * use <tt>null</tt> to represent the bootstrap class loader. This method |
|
1338 * will return <tt>null</tt> in such implementations if this class loader's |
|
1339 * parent is the bootstrap class loader. |
|
1340 * |
|
1341 * <p> If a security manager is present, and the invoker's class loader is |
|
1342 * not <tt>null</tt> and is not an ancestor of this class loader, then this |
|
1343 * method invokes the security manager's {@link |
|
1344 * SecurityManager#checkPermission(java.security.Permission) |
|
1345 * <tt>checkPermission</tt>} method with a {@link |
|
1346 * RuntimePermission#RuntimePermission(String) |
|
1347 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify |
|
1348 * access to the parent class loader is permitted. If not, a |
|
1349 * <tt>SecurityException</tt> will be thrown. </p> |
|
1350 * |
|
1351 * @return The parent <tt>ClassLoader</tt> |
|
1352 * |
|
1353 * @throws SecurityException |
|
1354 * If a security manager exists and its <tt>checkPermission</tt> |
|
1355 * method doesn't allow access to this class loader's parent class |
|
1356 * loader. |
|
1357 * |
|
1358 * @since 1.2 |
|
1359 */ |
|
1360 @CallerSensitive |
|
1361 public final ClassLoader getParent() { |
|
1362 if (parent == null) |
|
1363 return null; |
|
1364 SecurityManager sm = System.getSecurityManager(); |
|
1365 if (sm != null) { |
|
1366 checkClassLoaderPermission(this, Reflection.getCallerClass()); |
|
1367 } |
|
1368 return parent; |
|
1369 } |
|
1370 |
|
1371 /** |
|
1372 * Returns the system class loader for delegation. This is the default |
|
1373 * delegation parent for new <tt>ClassLoader</tt> instances, and is |
|
1374 * typically the class loader used to start the application. |
|
1375 * |
|
1376 * <p> This method is first invoked early in the runtime's startup |
|
1377 * sequence, at which point it creates the system class loader and sets it |
|
1378 * as the context class loader of the invoking <tt>Thread</tt>. |
|
1379 * |
|
1380 * <p> The default system class loader is an implementation-dependent |
|
1381 * instance of this class. |
|
1382 * |
|
1383 * <p> If the system property "<tt>java.system.class.loader</tt>" is defined |
|
1384 * when this method is first invoked then the value of that property is |
|
1385 * taken to be the name of a class that will be returned as the system |
|
1386 * class loader. The class is loaded using the default system class loader |
|
1387 * and must define a public constructor that takes a single parameter of |
|
1388 * type <tt>ClassLoader</tt> which is used as the delegation parent. An |
|
1389 * instance is then created using this constructor with the default system |
|
1390 * class loader as the parameter. The resulting class loader is defined |
|
1391 * to be the system class loader. |
|
1392 * |
|
1393 * <p> If a security manager is present, and the invoker's class loader is |
|
1394 * not <tt>null</tt> and the invoker's class loader is not the same as or |
|
1395 * an ancestor of the system class loader, then this method invokes the |
|
1396 * security manager's {@link |
|
1397 * SecurityManager#checkPermission(java.security.Permission) |
|
1398 * <tt>checkPermission</tt>} method with a {@link |
|
1399 * RuntimePermission#RuntimePermission(String) |
|
1400 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify |
|
1401 * access to the system class loader. If not, a |
|
1402 * <tt>SecurityException</tt> will be thrown. </p> |
|
1403 * |
|
1404 * @return The system <tt>ClassLoader</tt> for delegation, or |
|
1405 * <tt>null</tt> if none |
|
1406 * |
|
1407 * @throws SecurityException |
|
1408 * If a security manager exists and its <tt>checkPermission</tt> |
|
1409 * method doesn't allow access to the system class loader. |
|
1410 * |
|
1411 * @throws IllegalStateException |
|
1412 * If invoked recursively during the construction of the class |
|
1413 * loader specified by the "<tt>java.system.class.loader</tt>" |
|
1414 * property. |
|
1415 * |
|
1416 * @throws Error |
|
1417 * If the system property "<tt>java.system.class.loader</tt>" |
|
1418 * is defined but the named class could not be loaded, the |
|
1419 * provider class does not define the required constructor, or an |
|
1420 * exception is thrown by that constructor when it is invoked. The |
|
1421 * underlying cause of the error can be retrieved via the |
|
1422 * {@link Throwable#getCause()} method. |
|
1423 * |
|
1424 * @revised 1.4 |
|
1425 */ |
|
1426 @CallerSensitive |
|
1427 public static ClassLoader getSystemClassLoader() { |
|
1428 initSystemClassLoader(); |
|
1429 if (scl == null) { |
|
1430 return null; |
|
1431 } |
|
1432 SecurityManager sm = System.getSecurityManager(); |
|
1433 if (sm != null) { |
|
1434 checkClassLoaderPermission(scl, Reflection.getCallerClass()); |
|
1435 } |
|
1436 return scl; |
|
1437 } |
|
1438 |
|
1439 private static synchronized void initSystemClassLoader() { |
|
1440 if (!sclSet) { |
|
1441 if (scl != null) |
|
1442 throw new IllegalStateException("recursive invocation"); |
|
1443 sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); |
|
1444 if (l != null) { |
|
1445 Throwable oops = null; |
|
1446 scl = l.getClassLoader(); |
|
1447 try { |
|
1448 scl = AccessController.doPrivileged( |
|
1449 new SystemClassLoaderAction(scl)); |
|
1450 } catch (PrivilegedActionException pae) { |
|
1451 oops = pae.getCause(); |
|
1452 if (oops instanceof InvocationTargetException) { |
|
1453 oops = oops.getCause(); |
|
1454 } |
|
1455 } |
|
1456 if (oops != null) { |
|
1457 if (oops instanceof Error) { |
|
1458 throw (Error) oops; |
|
1459 } else { |
|
1460 // wrap the exception |
|
1461 throw new Error(oops); |
|
1462 } |
|
1463 } |
|
1464 } |
|
1465 sclSet = true; |
|
1466 } |
|
1467 } |
|
1468 |
|
1469 // Returns true if the specified class loader can be found in this class |
|
1470 // loader's delegation chain. |
|
1471 boolean isAncestor(ClassLoader cl) { |
|
1472 ClassLoader acl = this; |
|
1473 do { |
|
1474 acl = acl.parent; |
|
1475 if (cl == acl) { |
|
1476 return true; |
|
1477 } |
|
1478 } while (acl != null); |
|
1479 return false; |
|
1480 } |
|
1481 |
|
1482 // Tests if class loader access requires "getClassLoader" permission |
|
1483 // check. A class loader 'from' can access class loader 'to' if |
|
1484 // class loader 'from' is same as class loader 'to' or an ancestor |
|
1485 // of 'to'. The class loader in a system domain can access |
|
1486 // any class loader. |
|
1487 private static boolean needsClassLoaderPermissionCheck(ClassLoader from, |
|
1488 ClassLoader to) |
|
1489 { |
|
1490 if (from == to) |
|
1491 return false; |
|
1492 |
|
1493 if (from == null) |
|
1494 return false; |
|
1495 |
|
1496 return !to.isAncestor(from); |
|
1497 } |
|
1498 |
|
1499 // Returns the class's class loader, or null if none. |
|
1500 static ClassLoader getClassLoader(Class<?> caller) { |
|
1501 // This can be null if the VM is requesting it |
|
1502 if (caller == null) { |
|
1503 return null; |
|
1504 } |
|
1505 // Circumvent security check since this is package-private |
|
1506 return caller.getClassLoader0(); |
|
1507 } |
|
1508 |
|
1509 static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) { |
|
1510 SecurityManager sm = System.getSecurityManager(); |
|
1511 if (sm != null) { |
|
1512 // caller can be null if the VM is requesting it |
|
1513 ClassLoader ccl = getClassLoader(caller); |
|
1514 if (needsClassLoaderPermissionCheck(ccl, cl)) { |
|
1515 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); |
|
1516 } |
|
1517 } |
|
1518 } |
|
1519 |
|
1520 // The class loader for the system |
|
1521 // @GuardedBy("ClassLoader.class") |
|
1522 private static ClassLoader scl; |
|
1523 |
|
1524 // Set to true once the system class loader has been set |
|
1525 // @GuardedBy("ClassLoader.class") |
|
1526 private static boolean sclSet; |
|
1527 |
|
1528 |
|
1529 // -- Package -- |
|
1530 |
|
1531 /** |
|
1532 * Defines a package by name in this <tt>ClassLoader</tt>. This allows |
|
1533 * class loaders to define the packages for their classes. Packages must |
|
1534 * be created before the class is defined, and package names must be |
|
1535 * unique within a class loader and cannot be redefined or changed once |
|
1536 * created. |
|
1537 * |
|
1538 * @param name |
|
1539 * The package name |
|
1540 * |
|
1541 * @param specTitle |
|
1542 * The specification title |
|
1543 * |
|
1544 * @param specVersion |
|
1545 * The specification version |
|
1546 * |
|
1547 * @param specVendor |
|
1548 * The specification vendor |
|
1549 * |
|
1550 * @param implTitle |
|
1551 * The implementation title |
|
1552 * |
|
1553 * @param implVersion |
|
1554 * The implementation version |
|
1555 * |
|
1556 * @param implVendor |
|
1557 * The implementation vendor |
|
1558 * |
|
1559 * @param sealBase |
|
1560 * If not <tt>null</tt>, then this package is sealed with |
|
1561 * respect to the given code source {@link java.net.URL |
|
1562 * <tt>URL</tt>} object. Otherwise, the package is not sealed. |
|
1563 * |
|
1564 * @return The newly defined <tt>Package</tt> object |
|
1565 * |
|
1566 * @throws IllegalArgumentException |
|
1567 * If package name duplicates an existing package either in this |
|
1568 * class loader or one of its ancestors |
|
1569 * |
|
1570 * @since 1.2 |
|
1571 */ |
|
1572 protected Package definePackage(String name, String specTitle, |
|
1573 String specVersion, String specVendor, |
|
1574 String implTitle, String implVersion, |
|
1575 String implVendor, URL sealBase) |
|
1576 throws IllegalArgumentException |
|
1577 { |
|
1578 synchronized (packages) { |
|
1579 Package pkg = getPackage(name); |
|
1580 if (pkg != null) { |
|
1581 throw new IllegalArgumentException(name); |
|
1582 } |
|
1583 pkg = new Package(name, specTitle, specVersion, specVendor, |
|
1584 implTitle, implVersion, implVendor, |
|
1585 sealBase, this); |
|
1586 packages.put(name, pkg); |
|
1587 return pkg; |
|
1588 } |
|
1589 } |
|
1590 |
|
1591 /** |
|
1592 * Returns a <tt>Package</tt> that has been defined by this class loader |
|
1593 * or any of its ancestors. |
|
1594 * |
|
1595 * @param name |
|
1596 * The package name |
|
1597 * |
|
1598 * @return The <tt>Package</tt> corresponding to the given name, or |
|
1599 * <tt>null</tt> if not found |
|
1600 * |
|
1601 * @since 1.2 |
|
1602 */ |
|
1603 protected Package getPackage(String name) { |
|
1604 Package pkg; |
|
1605 synchronized (packages) { |
|
1606 pkg = packages.get(name); |
|
1607 } |
|
1608 if (pkg == null) { |
|
1609 if (parent != null) { |
|
1610 pkg = parent.getPackage(name); |
|
1611 } else { |
|
1612 pkg = Package.getSystemPackage(name); |
|
1613 } |
|
1614 if (pkg != null) { |
|
1615 synchronized (packages) { |
|
1616 Package pkg2 = packages.get(name); |
|
1617 if (pkg2 == null) { |
|
1618 packages.put(name, pkg); |
|
1619 } else { |
|
1620 pkg = pkg2; |
|
1621 } |
|
1622 } |
|
1623 } |
|
1624 } |
|
1625 return pkg; |
|
1626 } |
|
1627 |
|
1628 /** |
|
1629 * Returns all of the <tt>Packages</tt> defined by this class loader and |
|
1630 * its ancestors. |
|
1631 * |
|
1632 * @return The array of <tt>Package</tt> objects defined by this |
|
1633 * <tt>ClassLoader</tt> |
|
1634 * |
|
1635 * @since 1.2 |
|
1636 */ |
|
1637 protected Package[] getPackages() { |
|
1638 Map<String, Package> map; |
|
1639 synchronized (packages) { |
|
1640 map = new HashMap<>(packages); |
|
1641 } |
|
1642 Package[] pkgs; |
|
1643 if (parent != null) { |
|
1644 pkgs = parent.getPackages(); |
|
1645 } else { |
|
1646 pkgs = Package.getSystemPackages(); |
|
1647 } |
|
1648 if (pkgs != null) { |
|
1649 for (Package pkg : pkgs) { |
|
1650 String pkgName = pkg.getName(); |
|
1651 if (map.get(pkgName) == null) { |
|
1652 map.put(pkgName, pkg); |
|
1653 } |
|
1654 } |
|
1655 } |
|
1656 return map.values().toArray(new Package[map.size()]); |
|
1657 } |
|
1658 |
|
1659 |
|
1660 // -- Native library access -- |
|
1661 |
|
1662 /** |
|
1663 * Returns the absolute path name of a native library. The VM invokes this |
|
1664 * method to locate the native libraries that belong to classes loaded with |
|
1665 * this class loader. If this method returns <tt>null</tt>, the VM |
|
1666 * searches the library along the path specified as the |
|
1667 * "<tt>java.library.path</tt>" property. |
|
1668 * |
|
1669 * @param libname |
|
1670 * The library name |
|
1671 * |
|
1672 * @return The absolute path of the native library |
|
1673 * |
|
1674 * @see System#loadLibrary(String) |
|
1675 * @see System#mapLibraryName(String) |
|
1676 * |
|
1677 * @since 1.2 |
|
1678 */ |
|
1679 protected String findLibrary(String libname) { |
|
1680 return null; |
|
1681 } |
|
1682 |
|
1683 /** |
|
1684 * The inner class NativeLibrary denotes a loaded native library instance. |
|
1685 * Every classloader contains a vector of loaded native libraries in the |
|
1686 * private field <tt>nativeLibraries</tt>. The native libraries loaded |
|
1687 * into the system are entered into the <tt>systemNativeLibraries</tt> |
|
1688 * vector. |
|
1689 * |
|
1690 * <p> Every native library requires a particular version of JNI. This is |
|
1691 * denoted by the private <tt>jniVersion</tt> field. This field is set by |
|
1692 * the VM when it loads the library, and used by the VM to pass the correct |
|
1693 * version of JNI to the native methods. </p> |
|
1694 * |
|
1695 * @see ClassLoader |
|
1696 * @since 1.2 |
|
1697 */ |
|
1698 static class NativeLibrary { |
|
1699 // opaque handle to native library, used in native code. |
|
1700 long handle; |
|
1701 // the version of JNI environment the native library requires. |
|
1702 private int jniVersion; |
|
1703 // the class from which the library is loaded, also indicates |
|
1704 // the loader this native library belongs. |
|
1705 private final Class<?> fromClass; |
|
1706 // the canonicalized name of the native library. |
|
1707 // or static library name |
|
1708 String name; |
|
1709 // Indicates if the native library is linked into the VM |
|
1710 boolean isBuiltin; |
|
1711 // Indicates if the native library is loaded |
|
1712 boolean loaded; |
|
1713 native void load(String name, boolean isBuiltin); |
|
1714 |
|
1715 native long find(String name); |
|
1716 native void unload(String name, boolean isBuiltin); |
|
1717 static native String findBuiltinLib(String name); |
|
1718 |
|
1719 public NativeLibrary(Class<?> fromClass, String name, boolean isBuiltin) { |
|
1720 this.name = name; |
|
1721 this.fromClass = fromClass; |
|
1722 this.isBuiltin = isBuiltin; |
|
1723 } |
|
1724 |
|
1725 protected void finalize() { |
|
1726 synchronized (loadedLibraryNames) { |
|
1727 if (fromClass.getClassLoader() != null && loaded) { |
|
1728 /* remove the native library name */ |
|
1729 int size = loadedLibraryNames.size(); |
|
1730 for (int i = 0; i < size; i++) { |
|
1731 if (name.equals(loadedLibraryNames.elementAt(i))) { |
|
1732 loadedLibraryNames.removeElementAt(i); |
|
1733 break; |
|
1734 } |
|
1735 } |
|
1736 /* unload the library. */ |
|
1737 ClassLoader.nativeLibraryContext.push(this); |
|
1738 try { |
|
1739 unload(name, isBuiltin); |
|
1740 } finally { |
|
1741 ClassLoader.nativeLibraryContext.pop(); |
|
1742 } |
|
1743 } |
|
1744 } |
|
1745 } |
|
1746 // Invoked in the VM to determine the context class in |
|
1747 // JNI_Load/JNI_Unload |
|
1748 static Class<?> getFromClass() { |
|
1749 return ClassLoader.nativeLibraryContext.peek().fromClass; |
|
1750 } |
|
1751 } |
|
1752 |
|
1753 // All native library names we've loaded. |
|
1754 private static Vector<String> loadedLibraryNames = new Vector<>(); |
|
1755 |
|
1756 // Native libraries belonging to system classes. |
|
1757 private static Vector<NativeLibrary> systemNativeLibraries |
|
1758 = new Vector<>(); |
|
1759 |
|
1760 // Native libraries associated with the class loader. |
|
1761 private Vector<NativeLibrary> nativeLibraries = new Vector<>(); |
|
1762 |
|
1763 // native libraries being loaded/unloaded. |
|
1764 private static Stack<NativeLibrary> nativeLibraryContext = new Stack<>(); |
|
1765 |
|
1766 // The paths searched for libraries |
|
1767 private static String usr_paths[]; |
|
1768 private static String sys_paths[]; |
|
1769 |
|
1770 private static String[] initializePath(String propname) { |
|
1771 String ldpath = System.getProperty(propname, ""); |
|
1772 String ps = File.pathSeparator; |
|
1773 int ldlen = ldpath.length(); |
|
1774 int i, j, n; |
|
1775 // Count the separators in the path |
|
1776 i = ldpath.indexOf(ps); |
|
1777 n = 0; |
|
1778 while (i >= 0) { |
|
1779 n++; |
|
1780 i = ldpath.indexOf(ps, i + 1); |
|
1781 } |
|
1782 |
|
1783 // allocate the array of paths - n :'s = n + 1 path elements |
|
1784 String[] paths = new String[n + 1]; |
|
1785 |
|
1786 // Fill the array with paths from the ldpath |
|
1787 n = i = 0; |
|
1788 j = ldpath.indexOf(ps); |
|
1789 while (j >= 0) { |
|
1790 if (j - i > 0) { |
|
1791 paths[n++] = ldpath.substring(i, j); |
|
1792 } else if (j - i == 0) { |
|
1793 paths[n++] = "."; |
|
1794 } |
|
1795 i = j + 1; |
|
1796 j = ldpath.indexOf(ps, i); |
|
1797 } |
|
1798 paths[n] = ldpath.substring(i, ldlen); |
|
1799 return paths; |
|
1800 } |
|
1801 |
|
1802 // Invoked in the java.lang.Runtime class to implement load and loadLibrary. |
|
1803 static void loadLibrary(Class<?> fromClass, String name, |
|
1804 boolean isAbsolute) { |
|
1805 ClassLoader loader = |
|
1806 (fromClass == null) ? null : fromClass.getClassLoader(); |
|
1807 if (sys_paths == null) { |
|
1808 usr_paths = initializePath("java.library.path"); |
|
1809 sys_paths = initializePath("sun.boot.library.path"); |
|
1810 } |
|
1811 if (isAbsolute) { |
|
1812 if (loadLibrary0(fromClass, new File(name))) { |
|
1813 return; |
|
1814 } |
|
1815 throw new UnsatisfiedLinkError("Can't load library: " + name); |
|
1816 } |
|
1817 if (loader != null) { |
|
1818 String libfilename = loader.findLibrary(name); |
|
1819 if (libfilename != null) { |
|
1820 File libfile = new File(libfilename); |
|
1821 if (!libfile.isAbsolute()) { |
|
1822 throw new UnsatisfiedLinkError( |
|
1823 "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); |
|
1824 } |
|
1825 if (loadLibrary0(fromClass, libfile)) { |
|
1826 return; |
|
1827 } |
|
1828 throw new UnsatisfiedLinkError("Can't load " + libfilename); |
|
1829 } |
|
1830 } |
|
1831 for (String sys_path : sys_paths) { |
|
1832 File libfile = new File(sys_path, System.mapLibraryName(name)); |
|
1833 if (loadLibrary0(fromClass, libfile)) { |
|
1834 return; |
|
1835 } |
|
1836 libfile = ClassLoaderHelper.mapAlternativeName(libfile); |
|
1837 if (libfile != null && loadLibrary0(fromClass, libfile)) { |
|
1838 return; |
|
1839 } |
|
1840 } |
|
1841 if (loader != null) { |
|
1842 for (String usr_path : usr_paths) { |
|
1843 File libfile = new File(usr_path, System.mapLibraryName(name)); |
|
1844 if (loadLibrary0(fromClass, libfile)) { |
|
1845 return; |
|
1846 } |
|
1847 libfile = ClassLoaderHelper.mapAlternativeName(libfile); |
|
1848 if (libfile != null && loadLibrary0(fromClass, libfile)) { |
|
1849 return; |
|
1850 } |
|
1851 } |
|
1852 } |
|
1853 // Oops, it failed |
|
1854 throw new UnsatisfiedLinkError("no " + name + " in java.library.path"); |
|
1855 } |
|
1856 |
|
1857 private static boolean loadLibrary0(Class<?> fromClass, final File file) { |
|
1858 // Check to see if we're attempting to access a static library |
|
1859 String name = NativeLibrary.findBuiltinLib(file.getName()); |
|
1860 boolean isBuiltin = (name != null); |
|
1861 if (!isBuiltin) { |
|
1862 name = AccessController.doPrivileged( |
|
1863 new PrivilegedAction<String>() { |
|
1864 public String run() { |
|
1865 try { |
|
1866 return file.exists() ? file.getCanonicalPath() : null; |
|
1867 } catch (IOException e) { |
|
1868 return null; |
|
1869 } |
|
1870 } |
|
1871 }); |
|
1872 if (name == null) { |
|
1873 return false; |
|
1874 } |
|
1875 } |
|
1876 ClassLoader loader = |
|
1877 (fromClass == null) ? null : fromClass.getClassLoader(); |
|
1878 Vector<NativeLibrary> libs = |
|
1879 loader != null ? loader.nativeLibraries : systemNativeLibraries; |
|
1880 synchronized (libs) { |
|
1881 int size = libs.size(); |
|
1882 for (int i = 0; i < size; i++) { |
|
1883 NativeLibrary lib = libs.elementAt(i); |
|
1884 if (name.equals(lib.name)) { |
|
1885 return true; |
|
1886 } |
|
1887 } |
|
1888 |
|
1889 synchronized (loadedLibraryNames) { |
|
1890 if (loadedLibraryNames.contains(name)) { |
|
1891 throw new UnsatisfiedLinkError |
|
1892 ("Native Library " + |
|
1893 name + |
|
1894 " already loaded in another classloader"); |
|
1895 } |
|
1896 /* If the library is being loaded (must be by the same thread, |
|
1897 * because Runtime.load and Runtime.loadLibrary are |
|
1898 * synchronous). The reason is can occur is that the JNI_OnLoad |
|
1899 * function can cause another loadLibrary invocation. |
|
1900 * |
|
1901 * Thus we can use a static stack to hold the list of libraries |
|
1902 * we are loading. |
|
1903 * |
|
1904 * If there is a pending load operation for the library, we |
|
1905 * immediately return success; otherwise, we raise |
|
1906 * UnsatisfiedLinkError. |
|
1907 */ |
|
1908 int n = nativeLibraryContext.size(); |
|
1909 for (int i = 0; i < n; i++) { |
|
1910 NativeLibrary lib = nativeLibraryContext.elementAt(i); |
|
1911 if (name.equals(lib.name)) { |
|
1912 if (loader == lib.fromClass.getClassLoader()) { |
|
1913 return true; |
|
1914 } else { |
|
1915 throw new UnsatisfiedLinkError |
|
1916 ("Native Library " + |
|
1917 name + |
|
1918 " is being loaded in another classloader"); |
|
1919 } |
|
1920 } |
|
1921 } |
|
1922 NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin); |
|
1923 nativeLibraryContext.push(lib); |
|
1924 try { |
|
1925 lib.load(name, isBuiltin); |
|
1926 } finally { |
|
1927 nativeLibraryContext.pop(); |
|
1928 } |
|
1929 if (lib.loaded) { |
|
1930 loadedLibraryNames.addElement(name); |
|
1931 libs.addElement(lib); |
|
1932 return true; |
|
1933 } |
|
1934 return false; |
|
1935 } |
|
1936 } |
|
1937 } |
|
1938 |
|
1939 // Invoked in the VM class linking code. |
|
1940 static long findNative(ClassLoader loader, String name) { |
|
1941 Vector<NativeLibrary> libs = |
|
1942 loader != null ? loader.nativeLibraries : systemNativeLibraries; |
|
1943 synchronized (libs) { |
|
1944 int size = libs.size(); |
|
1945 for (int i = 0; i < size; i++) { |
|
1946 NativeLibrary lib = libs.elementAt(i); |
|
1947 long entry = lib.find(name); |
|
1948 if (entry != 0) |
|
1949 return entry; |
|
1950 } |
|
1951 } |
|
1952 return 0; |
|
1953 } |
|
1954 |
|
1955 |
|
1956 // -- Assertion management -- |
|
1957 |
|
1958 final Object assertionLock; |
|
1959 |
|
1960 // The default toggle for assertion checking. |
|
1961 // @GuardedBy("assertionLock") |
|
1962 private boolean defaultAssertionStatus = false; |
|
1963 |
|
1964 // Maps String packageName to Boolean package default assertion status Note |
|
1965 // that the default package is placed under a null map key. If this field |
|
1966 // is null then we are delegating assertion status queries to the VM, i.e., |
|
1967 // none of this ClassLoader's assertion status modification methods have |
|
1968 // been invoked. |
|
1969 // @GuardedBy("assertionLock") |
|
1970 private Map<String, Boolean> packageAssertionStatus = null; |
|
1971 |
|
1972 // Maps String fullyQualifiedClassName to Boolean assertionStatus If this |
|
1973 // field is null then we are delegating assertion status queries to the VM, |
|
1974 // i.e., none of this ClassLoader's assertion status modification methods |
|
1975 // have been invoked. |
|
1976 // @GuardedBy("assertionLock") |
|
1977 Map<String, Boolean> classAssertionStatus = null; |
|
1978 |
|
1979 /** |
|
1980 * Sets the default assertion status for this class loader. This setting |
|
1981 * determines whether classes loaded by this class loader and initialized |
|
1982 * in the future will have assertions enabled or disabled by default. |
|
1983 * This setting may be overridden on a per-package or per-class basis by |
|
1984 * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link |
|
1985 * #setClassAssertionStatus(String, boolean)}. |
|
1986 * |
|
1987 * @param enabled |
|
1988 * <tt>true</tt> if classes loaded by this class loader will |
|
1989 * henceforth have assertions enabled by default, <tt>false</tt> |
|
1990 * if they will have assertions disabled by default. |
|
1991 * |
|
1992 * @since 1.4 |
|
1993 */ |
|
1994 public void setDefaultAssertionStatus(boolean enabled) { |
|
1995 synchronized (assertionLock) { |
|
1996 if (classAssertionStatus == null) |
|
1997 initializeJavaAssertionMaps(); |
|
1998 |
|
1999 defaultAssertionStatus = enabled; |
|
2000 } |
|
2001 } |
|
2002 |
|
2003 /** |
|
2004 * Sets the package default assertion status for the named package. The |
|
2005 * package default assertion status determines the assertion status for |
|
2006 * classes initialized in the future that belong to the named package or |
|
2007 * any of its "subpackages". |
|
2008 * |
|
2009 * <p> A subpackage of a package named p is any package whose name begins |
|
2010 * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a |
|
2011 * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and |
|
2012 * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>. |
|
2013 * |
|
2014 * <p> In the event that multiple package defaults apply to a given class, |
|
2015 * the package default pertaining to the most specific package takes |
|
2016 * precedence over the others. For example, if <tt>javax.lang</tt> and |
|
2017 * <tt>javax.lang.reflect</tt> both have package defaults associated with |
|
2018 * them, the latter package default applies to classes in |
|
2019 * <tt>javax.lang.reflect</tt>. |
|
2020 * |
|
2021 * <p> Package defaults take precedence over the class loader's default |
|
2022 * assertion status, and may be overridden on a per-class basis by invoking |
|
2023 * {@link #setClassAssertionStatus(String, boolean)}. </p> |
|
2024 * |
|
2025 * @param packageName |
|
2026 * The name of the package whose package default assertion status |
|
2027 * is to be set. A <tt>null</tt> value indicates the unnamed |
|
2028 * package that is "current" |
|
2029 * (see section 7.4.2 of |
|
2030 * <cite>The Java™ Language Specification</cite>.) |
|
2031 * |
|
2032 * @param enabled |
|
2033 * <tt>true</tt> if classes loaded by this classloader and |
|
2034 * belonging to the named package or any of its subpackages will |
|
2035 * have assertions enabled by default, <tt>false</tt> if they will |
|
2036 * have assertions disabled by default. |
|
2037 * |
|
2038 * @since 1.4 |
|
2039 */ |
|
2040 public void setPackageAssertionStatus(String packageName, |
|
2041 boolean enabled) { |
|
2042 synchronized (assertionLock) { |
|
2043 if (packageAssertionStatus == null) |
|
2044 initializeJavaAssertionMaps(); |
|
2045 |
|
2046 packageAssertionStatus.put(packageName, enabled); |
|
2047 } |
|
2048 } |
|
2049 |
|
2050 /** |
|
2051 * Sets the desired assertion status for the named top-level class in this |
|
2052 * class loader and any nested classes contained therein. This setting |
|
2053 * takes precedence over the class loader's default assertion status, and |
|
2054 * over any applicable per-package default. This method has no effect if |
|
2055 * the named class has already been initialized. (Once a class is |
|
2056 * initialized, its assertion status cannot change.) |
|
2057 * |
|
2058 * <p> If the named class is not a top-level class, this invocation will |
|
2059 * have no effect on the actual assertion status of any class. </p> |
|
2060 * |
|
2061 * @param className |
|
2062 * The fully qualified class name of the top-level class whose |
|
2063 * assertion status is to be set. |
|
2064 * |
|
2065 * @param enabled |
|
2066 * <tt>true</tt> if the named class is to have assertions |
|
2067 * enabled when (and if) it is initialized, <tt>false</tt> if the |
|
2068 * class is to have assertions disabled. |
|
2069 * |
|
2070 * @since 1.4 |
|
2071 */ |
|
2072 public void setClassAssertionStatus(String className, boolean enabled) { |
|
2073 synchronized (assertionLock) { |
|
2074 if (classAssertionStatus == null) |
|
2075 initializeJavaAssertionMaps(); |
|
2076 |
|
2077 classAssertionStatus.put(className, enabled); |
|
2078 } |
|
2079 } |
|
2080 |
|
2081 /** |
|
2082 * Sets the default assertion status for this class loader to |
|
2083 * <tt>false</tt> and discards any package defaults or class assertion |
|
2084 * status settings associated with the class loader. This method is |
|
2085 * provided so that class loaders can be made to ignore any command line or |
|
2086 * persistent assertion status settings and "start with a clean slate." |
|
2087 * |
|
2088 * @since 1.4 |
|
2089 */ |
|
2090 public void clearAssertionStatus() { |
|
2091 /* |
|
2092 * Whether or not "Java assertion maps" are initialized, set |
|
2093 * them to empty maps, effectively ignoring any present settings. |
|
2094 */ |
|
2095 synchronized (assertionLock) { |
|
2096 classAssertionStatus = new HashMap<>(); |
|
2097 packageAssertionStatus = new HashMap<>(); |
|
2098 defaultAssertionStatus = false; |
|
2099 } |
|
2100 } |
|
2101 |
|
2102 /** |
|
2103 * Returns the assertion status that would be assigned to the specified |
|
2104 * class if it were to be initialized at the time this method is invoked. |
|
2105 * If the named class has had its assertion status set, the most recent |
|
2106 * setting will be returned; otherwise, if any package default assertion |
|
2107 * status pertains to this class, the most recent setting for the most |
|
2108 * specific pertinent package default assertion status is returned; |
|
2109 * otherwise, this class loader's default assertion status is returned. |
|
2110 * </p> |
|
2111 * |
|
2112 * @param className |
|
2113 * The fully qualified class name of the class whose desired |
|
2114 * assertion status is being queried. |
|
2115 * |
|
2116 * @return The desired assertion status of the specified class. |
|
2117 * |
|
2118 * @see #setClassAssertionStatus(String, boolean) |
|
2119 * @see #setPackageAssertionStatus(String, boolean) |
|
2120 * @see #setDefaultAssertionStatus(boolean) |
|
2121 * |
|
2122 * @since 1.4 |
|
2123 */ |
|
2124 boolean desiredAssertionStatus(String className) { |
|
2125 synchronized (assertionLock) { |
|
2126 // assert classAssertionStatus != null; |
|
2127 // assert packageAssertionStatus != null; |
|
2128 |
|
2129 // Check for a class entry |
|
2130 Boolean result = classAssertionStatus.get(className); |
|
2131 if (result != null) |
|
2132 return result.booleanValue(); |
|
2133 |
|
2134 // Check for most specific package entry |
|
2135 int dotIndex = className.lastIndexOf('.'); |
|
2136 if (dotIndex < 0) { // default package |
|
2137 result = packageAssertionStatus.get(null); |
|
2138 if (result != null) |
|
2139 return result.booleanValue(); |
|
2140 } |
|
2141 while(dotIndex > 0) { |
|
2142 className = className.substring(0, dotIndex); |
|
2143 result = packageAssertionStatus.get(className); |
|
2144 if (result != null) |
|
2145 return result.booleanValue(); |
|
2146 dotIndex = className.lastIndexOf('.', dotIndex-1); |
|
2147 } |
|
2148 |
|
2149 // Return the classloader default |
|
2150 return defaultAssertionStatus; |
|
2151 } |
|
2152 } |
|
2153 |
|
2154 // Set up the assertions with information provided by the VM. |
|
2155 // Note: Should only be called inside a synchronized block |
|
2156 private void initializeJavaAssertionMaps() { |
|
2157 // assert Thread.holdsLock(assertionLock); |
|
2158 |
|
2159 classAssertionStatus = new HashMap<>(); |
|
2160 packageAssertionStatus = new HashMap<>(); |
|
2161 AssertionStatusDirectives directives = retrieveDirectives(); |
|
2162 |
|
2163 for(int i = 0; i < directives.classes.length; i++) |
|
2164 classAssertionStatus.put(directives.classes[i], |
|
2165 directives.classEnabled[i]); |
|
2166 |
|
2167 for(int i = 0; i < directives.packages.length; i++) |
|
2168 packageAssertionStatus.put(directives.packages[i], |
|
2169 directives.packageEnabled[i]); |
|
2170 |
|
2171 defaultAssertionStatus = directives.deflt; |
|
2172 } |
|
2173 |
|
2174 // Retrieves the assertion directives from the VM. |
|
2175 private static native AssertionStatusDirectives retrieveDirectives(); |
|
2176 } |
|
2177 |
|
2178 |
|
2179 class SystemClassLoaderAction |
|
2180 implements PrivilegedExceptionAction<ClassLoader> { |
|
2181 private ClassLoader parent; |
|
2182 |
|
2183 SystemClassLoaderAction(ClassLoader parent) { |
|
2184 this.parent = parent; |
|
2185 } |
|
2186 |
|
2187 public ClassLoader run() throws Exception { |
|
2188 String cls = System.getProperty("java.system.class.loader"); |
|
2189 if (cls == null) { |
|
2190 return parent; |
|
2191 } |
|
2192 |
|
2193 Constructor<?> ctor = Class.forName(cls, true, parent) |
|
2194 .getDeclaredConstructor(new Class<?>[] { ClassLoader.class }); |
|
2195 ClassLoader sys = (ClassLoader) ctor.newInstance( |
|
2196 new Object[] { parent }); |
|
2197 Thread.currentThread().setContextClassLoader(sys); |
|
2198 return sys; |
|
2199 } |
|
2200 } |