1.1 --- a/emul/src/main/java/java/lang/ClassLoader.java Tue Oct 30 08:27:04 2012 +0100
1.2 +++ b/emul/src/main/java/java/lang/ClassLoader.java Tue Oct 30 09:24:41 2012 +0100
1.3 @@ -26,38 +26,9 @@
1.4
1.5 import java.io.InputStream;
1.6 import java.io.IOException;
1.7 -import java.io.File;
1.8 -import java.lang.reflect.Constructor;
1.9 -import java.lang.reflect.InvocationTargetException;
1.10 -import java.net.MalformedURLException;
1.11 import java.net.URL;
1.12 -import java.security.AccessController;
1.13 -import java.security.AccessControlContext;
1.14 -import java.security.CodeSource;
1.15 -import java.security.Policy;
1.16 -import java.security.PrivilegedAction;
1.17 -import java.security.PrivilegedActionException;
1.18 -import java.security.PrivilegedExceptionAction;
1.19 -import java.security.ProtectionDomain;
1.20 -import java.security.cert.Certificate;
1.21 -import java.util.Collections;
1.22 import java.util.Enumeration;
1.23 -import java.util.HashMap;
1.24 -import java.util.HashSet;
1.25 -import java.util.Set;
1.26 -import java.util.Stack;
1.27 -import java.util.Map;
1.28 -import java.util.Vector;
1.29 -import java.util.Hashtable;
1.30 -import java.util.WeakHashMap;
1.31 -import java.util.concurrent.ConcurrentHashMap;
1.32 -import sun.misc.ClassFileTransformer;
1.33 -import sun.misc.CompoundEnumeration;
1.34 -import sun.misc.Resource;
1.35 -import sun.misc.URLClassPath;
1.36 -import sun.misc.VM;
1.37 -import sun.reflect.Reflection;
1.38 -import sun.security.util.SecurityConstants;
1.39 +import java.util.NoSuchElementException;
1.40
1.41 /**
1.42 * A class loader is an object that is responsible for loading classes. The
1.43 @@ -186,111 +157,6 @@
1.44 // must be added *after* it.
1.45 private final ClassLoader parent;
1.46
1.47 - /**
1.48 - * Encapsulates the set of parallel capable loader types.
1.49 - */
1.50 - private static class ParallelLoaders {
1.51 - private ParallelLoaders() {}
1.52 -
1.53 - // the set of parallel capable loader types
1.54 - private static final Set<Class<? extends ClassLoader>> loaderTypes =
1.55 - Collections.newSetFromMap(
1.56 - new WeakHashMap<Class<? extends ClassLoader>, Boolean>());
1.57 - static {
1.58 - synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); }
1.59 - }
1.60 -
1.61 - /**
1.62 - * Registers the given class loader type as parallel capabale.
1.63 - * Returns {@code true} is successfully registered; {@code false} if
1.64 - * loader's super class is not registered.
1.65 - */
1.66 - static boolean register(Class<? extends ClassLoader> c) {
1.67 - synchronized (loaderTypes) {
1.68 - if (loaderTypes.contains(c.getSuperclass())) {
1.69 - // register the class loader as parallel capable
1.70 - // if and only if all of its super classes are.
1.71 - // Note: given current classloading sequence, if
1.72 - // the immediate super class is parallel capable,
1.73 - // all the super classes higher up must be too.
1.74 - loaderTypes.add(c);
1.75 - return true;
1.76 - } else {
1.77 - return false;
1.78 - }
1.79 - }
1.80 - }
1.81 -
1.82 - /**
1.83 - * Returns {@code true} if the given class loader type is
1.84 - * registered as parallel capable.
1.85 - */
1.86 - static boolean isRegistered(Class<? extends ClassLoader> c) {
1.87 - synchronized (loaderTypes) {
1.88 - return loaderTypes.contains(c);
1.89 - }
1.90 - }
1.91 - }
1.92 -
1.93 - // Maps class name to the corresponding lock object when the current
1.94 - // class loader is parallel capable.
1.95 - // Note: VM also uses this field to decide if the current class loader
1.96 - // is parallel capable and the appropriate lock object for class loading.
1.97 - private final ConcurrentHashMap<String, Object> parallelLockMap;
1.98 -
1.99 - // Hashtable that maps packages to certs
1.100 - private final Map <String, Certificate[]> package2certs;
1.101 -
1.102 - // Shared among all packages with unsigned classes
1.103 - private static final Certificate[] nocerts = new Certificate[0];
1.104 -
1.105 - // The classes loaded by this class loader. The only purpose of this table
1.106 - // is to keep the classes from being GC'ed until the loader is GC'ed.
1.107 - private final Vector<Class<?>> classes = new Vector<>();
1.108 -
1.109 - // The "default" domain. Set as the default ProtectionDomain on newly
1.110 - // created classes.
1.111 - private final ProtectionDomain defaultDomain =
1.112 - new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
1.113 - null, this, null);
1.114 -
1.115 - // The initiating protection domains for all classes loaded by this loader
1.116 - private final Set<ProtectionDomain> domains;
1.117 -
1.118 - // Invoked by the VM to record every loaded class with this loader.
1.119 - void addClass(Class c) {
1.120 - classes.addElement(c);
1.121 - }
1.122 -
1.123 - // The packages defined in this class loader. Each package name is mapped
1.124 - // to its corresponding Package object.
1.125 - // @GuardedBy("itself")
1.126 - private final HashMap<String, Package> packages = new HashMap<>();
1.127 -
1.128 - private static Void checkCreateClassLoader() {
1.129 - SecurityManager security = System.getSecurityManager();
1.130 - if (security != null) {
1.131 - security.checkCreateClassLoader();
1.132 - }
1.133 - return null;
1.134 - }
1.135 -
1.136 - private ClassLoader(Void unused, ClassLoader parent) {
1.137 - this.parent = parent;
1.138 - if (ParallelLoaders.isRegistered(this.getClass())) {
1.139 - parallelLockMap = new ConcurrentHashMap<>();
1.140 - package2certs = new ConcurrentHashMap<>();
1.141 - domains =
1.142 - Collections.synchronizedSet(new HashSet<ProtectionDomain>());
1.143 - assertionLock = new Object();
1.144 - } else {
1.145 - // no finer-grained lock; lock on the classloader instance
1.146 - parallelLockMap = null;
1.147 - package2certs = new Hashtable<>();
1.148 - domains = new HashSet<>();
1.149 - assertionLock = this;
1.150 - }
1.151 - }
1.152
1.153 /**
1.154 * Creates a new class loader using the specified parent class loader for
1.155 @@ -312,7 +178,7 @@
1.156 * @since 1.2
1.157 */
1.158 protected ClassLoader(ClassLoader parent) {
1.159 - this(checkCreateClassLoader(), parent);
1.160 + throw new SecurityException();
1.161 }
1.162
1.163 /**
1.164 @@ -331,7 +197,7 @@
1.165 * of a new class loader.
1.166 */
1.167 protected ClassLoader() {
1.168 - this(checkCreateClassLoader(), getSystemClassLoader());
1.169 + throw new SecurityException();
1.170 }
1.171
1.172 // -- Class --
1.173 @@ -404,7 +270,6 @@
1.174 // First, check if the class has already been loaded
1.175 Class c = findLoadedClass(name);
1.176 if (c == null) {
1.177 - long t0 = System.nanoTime();
1.178 try {
1.179 if (parent != null) {
1.180 c = parent.loadClass(name, false);
1.181 @@ -419,13 +284,12 @@
1.182 if (c == null) {
1.183 // If still not found, then invoke findClass in order
1.184 // to find the class.
1.185 - long t1 = System.nanoTime();
1.186 c = findClass(name);
1.187
1.188 - // this is the defining class loader; record the stats
1.189 - sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
1.190 - sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
1.191 - sun.misc.PerfCounter.getFindClasses().increment();
1.192 +// // this is the defining class loader; record the stats
1.193 +// sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
1.194 +// sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
1.195 +// sun.misc.PerfCounter.getFindClasses().increment();
1.196 }
1.197 }
1.198 if (resolve) {
1.199 @@ -457,49 +321,9 @@
1.200 */
1.201 protected Object getClassLoadingLock(String className) {
1.202 Object lock = this;
1.203 - if (parallelLockMap != null) {
1.204 - Object newLock = new Object();
1.205 - lock = parallelLockMap.putIfAbsent(className, newLock);
1.206 - if (lock == null) {
1.207 - lock = newLock;
1.208 - }
1.209 - }
1.210 return lock;
1.211 }
1.212
1.213 - // This method is invoked by the virtual machine to load a class.
1.214 - private Class loadClassInternal(String name)
1.215 - throws ClassNotFoundException
1.216 - {
1.217 - // For backward compatibility, explicitly lock on 'this' when
1.218 - // the current class loader is not parallel capable.
1.219 - if (parallelLockMap == null) {
1.220 - synchronized (this) {
1.221 - return loadClass(name);
1.222 - }
1.223 - } else {
1.224 - return loadClass(name);
1.225 - }
1.226 - }
1.227 -
1.228 - // Invoked by the VM after loading class with this loader.
1.229 - private void checkPackageAccess(Class cls, ProtectionDomain pd) {
1.230 - final SecurityManager sm = System.getSecurityManager();
1.231 - if (sm != null) {
1.232 - final String name = cls.getName();
1.233 - final int i = name.lastIndexOf('.');
1.234 - if (i != -1) {
1.235 - AccessController.doPrivileged(new PrivilegedAction<Void>() {
1.236 - public Void run() {
1.237 - sm.checkPackageAccess(name.substring(0, i));
1.238 - return null;
1.239 - }
1.240 - }, new AccessControlContext(new ProtectionDomain[] {pd}));
1.241 - }
1.242 - }
1.243 - domains.add(pd);
1.244 - }
1.245 -
1.246 /**
1.247 * Finds the class with the specified <a href="#name">binary name</a>.
1.248 * This method should be overridden by class loader implementations that
1.249 @@ -567,7 +391,7 @@
1.250 protected final Class<?> defineClass(byte[] b, int off, int len)
1.251 throws ClassFormatError
1.252 {
1.253 - return defineClass(null, b, off, len, null);
1.254 + throw new SecurityException();
1.255 }
1.256
1.257 /**
1.258 @@ -631,363 +455,7 @@
1.259 protected final Class<?> defineClass(String name, byte[] b, int off, int len)
1.260 throws ClassFormatError
1.261 {
1.262 - return defineClass(name, b, off, len, null);
1.263 - }
1.264 -
1.265 - /* Determine protection domain, and check that:
1.266 - - not define java.* class,
1.267 - - signer of this class matches signers for the rest of the classes in
1.268 - package.
1.269 - */
1.270 - private ProtectionDomain preDefineClass(String name,
1.271 - ProtectionDomain pd)
1.272 - {
1.273 - if (!checkName(name))
1.274 - throw new NoClassDefFoundError("IllegalName: " + name);
1.275 -
1.276 - if ((name != null) && name.startsWith("java.")) {
1.277 - throw new SecurityException
1.278 - ("Prohibited package name: " +
1.279 - name.substring(0, name.lastIndexOf('.')));
1.280 - }
1.281 - if (pd == null) {
1.282 - pd = defaultDomain;
1.283 - }
1.284 -
1.285 - if (name != null) checkCerts(name, pd.getCodeSource());
1.286 -
1.287 - return pd;
1.288 - }
1.289 -
1.290 - private String defineClassSourceLocation(ProtectionDomain pd)
1.291 - {
1.292 - CodeSource cs = pd.getCodeSource();
1.293 - String source = null;
1.294 - if (cs != null && cs.getLocation() != null) {
1.295 - source = cs.getLocation().toString();
1.296 - }
1.297 - return source;
1.298 - }
1.299 -
1.300 - private Class defineTransformedClass(String name, byte[] b, int off, int len,
1.301 - ProtectionDomain pd,
1.302 - ClassFormatError cfe, String source)
1.303 - throws ClassFormatError
1.304 - {
1.305 - // Class format error - try to transform the bytecode and
1.306 - // define the class again
1.307 - //
1.308 - ClassFileTransformer[] transformers =
1.309 - ClassFileTransformer.getTransformers();
1.310 - Class c = null;
1.311 -
1.312 - if (transformers != null) {
1.313 - for (ClassFileTransformer transformer : transformers) {
1.314 - try {
1.315 - // Transform byte code using transformer
1.316 - byte[] tb = transformer.transform(b, off, len);
1.317 - c = defineClass1(name, tb, 0, tb.length,
1.318 - pd, source);
1.319 - break;
1.320 - } catch (ClassFormatError cfe2) {
1.321 - // If ClassFormatError occurs, try next transformer
1.322 - }
1.323 - }
1.324 - }
1.325 -
1.326 - // Rethrow original ClassFormatError if unable to transform
1.327 - // bytecode to well-formed
1.328 - //
1.329 - if (c == null)
1.330 - throw cfe;
1.331 -
1.332 - return c;
1.333 - }
1.334 -
1.335 - private void postDefineClass(Class c, ProtectionDomain pd)
1.336 - {
1.337 - if (pd.getCodeSource() != null) {
1.338 - Certificate certs[] = pd.getCodeSource().getCertificates();
1.339 - if (certs != null)
1.340 - setSigners(c, certs);
1.341 - }
1.342 - }
1.343 -
1.344 - /**
1.345 - * Converts an array of bytes into an instance of class <tt>Class</tt>,
1.346 - * with an optional <tt>ProtectionDomain</tt>. If the domain is
1.347 - * <tt>null</tt>, then a default domain will be assigned to the class as
1.348 - * specified in the documentation for {@link #defineClass(String, byte[],
1.349 - * int, int)}. Before the class can be used it must be resolved.
1.350 - *
1.351 - * <p> The first class defined in a package determines the exact set of
1.352 - * certificates that all subsequent classes defined in that package must
1.353 - * contain. The set of certificates for a class is obtained from the
1.354 - * {@link java.security.CodeSource <tt>CodeSource</tt>} within the
1.355 - * <tt>ProtectionDomain</tt> of the class. Any classes added to that
1.356 - * package must contain the same set of certificates or a
1.357 - * <tt>SecurityException</tt> will be thrown. Note that if
1.358 - * <tt>name</tt> is <tt>null</tt>, this check is not performed.
1.359 - * You should always pass in the <a href="#name">binary name</a> of the
1.360 - * class you are defining as well as the bytes. This ensures that the
1.361 - * class you are defining is indeed the class you think it is.
1.362 - *
1.363 - * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since
1.364 - * all classes in the "<tt>java.*</tt> packages can only be defined by the
1.365 - * bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it
1.366 - * must be equal to the <a href="#name">binary name</a> of the class
1.367 - * specified by the byte array "<tt>b</tt>", otherwise a {@link
1.368 - * <tt>NoClassDefFoundError</tt>} will be thrown. </p>
1.369 - *
1.370 - * @param name
1.371 - * The expected <a href="#name">binary name</a> of the class, or
1.372 - * <tt>null</tt> if not known
1.373 - *
1.374 - * @param b
1.375 - * The bytes that make up the class data. The bytes in positions
1.376 - * <tt>off</tt> through <tt>off+len-1</tt> should have the format
1.377 - * of a valid class file as defined by
1.378 - * <cite>The Java™ Virtual Machine Specification</cite>.
1.379 - *
1.380 - * @param off
1.381 - * The start offset in <tt>b</tt> of the class data
1.382 - *
1.383 - * @param len
1.384 - * The length of the class data
1.385 - *
1.386 - * @param protectionDomain
1.387 - * The ProtectionDomain of the class
1.388 - *
1.389 - * @return The <tt>Class</tt> object created from the data,
1.390 - * and optional <tt>ProtectionDomain</tt>.
1.391 - *
1.392 - * @throws ClassFormatError
1.393 - * If the data did not contain a valid class
1.394 - *
1.395 - * @throws NoClassDefFoundError
1.396 - * If <tt>name</tt> is not equal to the <a href="#name">binary
1.397 - * name</a> of the class specified by <tt>b</tt>
1.398 - *
1.399 - * @throws IndexOutOfBoundsException
1.400 - * If either <tt>off</tt> or <tt>len</tt> is negative, or if
1.401 - * <tt>off+len</tt> is greater than <tt>b.length</tt>.
1.402 - *
1.403 - * @throws SecurityException
1.404 - * If an attempt is made to add this class to a package that
1.405 - * contains classes that were signed by a different set of
1.406 - * certificates than this class, or if <tt>name</tt> begins with
1.407 - * "<tt>java.</tt>".
1.408 - */
1.409 - protected final Class<?> defineClass(String name, byte[] b, int off, int len,
1.410 - ProtectionDomain protectionDomain)
1.411 - throws ClassFormatError
1.412 - {
1.413 - protectionDomain = preDefineClass(name, protectionDomain);
1.414 -
1.415 - Class c = null;
1.416 - String source = defineClassSourceLocation(protectionDomain);
1.417 -
1.418 - try {
1.419 - c = defineClass1(name, b, off, len, protectionDomain, source);
1.420 - } catch (ClassFormatError cfe) {
1.421 - c = defineTransformedClass(name, b, off, len, protectionDomain, cfe,
1.422 - source);
1.423 - }
1.424 -
1.425 - postDefineClass(c, protectionDomain);
1.426 - return c;
1.427 - }
1.428 -
1.429 - /**
1.430 - * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
1.431 - * into an instance of class <tt>Class</tt>,
1.432 - * with an optional <tt>ProtectionDomain</tt>. If the domain is
1.433 - * <tt>null</tt>, then a default domain will be assigned to the class as
1.434 - * specified in the documentation for {@link #defineClass(String, byte[],
1.435 - * int, int)}. Before the class can be used it must be resolved.
1.436 - *
1.437 - * <p>The rules about the first class defined in a package determining the
1.438 - * set of certificates for the package, and the restrictions on class names
1.439 - * are identical to those specified in the documentation for {@link
1.440 - * #defineClass(String, byte[], int, int, ProtectionDomain)}.
1.441 - *
1.442 - * <p> An invocation of this method of the form
1.443 - * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
1.444 - * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
1.445 - * result as the statements
1.446 - *
1.447 - * <blockquote><tt>
1.448 - * ...<br>
1.449 - * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link
1.450 - * java.nio.ByteBuffer#remaining remaining}()];<br>
1.451 - * </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
1.452 - * get}(temp);<br>
1.453 - * return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
1.454 - * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0,
1.455 - * temp.length, </tt><i>pd</i><tt>);<br>
1.456 - * </tt></blockquote>
1.457 - *
1.458 - * @param name
1.459 - * The expected <a href="#name">binary name</a>. of the class, or
1.460 - * <tt>null</tt> if not known
1.461 - *
1.462 - * @param b
1.463 - * The bytes that make up the class data. The bytes from positions
1.464 - * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1
1.465 - * </tt> should have the format of a valid class file as defined by
1.466 - * <cite>The Java™ Virtual Machine Specification</cite>.
1.467 - *
1.468 - * @param protectionDomain
1.469 - * The ProtectionDomain of the class, or <tt>null</tt>.
1.470 - *
1.471 - * @return The <tt>Class</tt> object created from the data,
1.472 - * and optional <tt>ProtectionDomain</tt>.
1.473 - *
1.474 - * @throws ClassFormatError
1.475 - * If the data did not contain a valid class.
1.476 - *
1.477 - * @throws NoClassDefFoundError
1.478 - * If <tt>name</tt> is not equal to the <a href="#name">binary
1.479 - * name</a> of the class specified by <tt>b</tt>
1.480 - *
1.481 - * @throws SecurityException
1.482 - * If an attempt is made to add this class to a package that
1.483 - * contains classes that were signed by a different set of
1.484 - * certificates than this class, or if <tt>name</tt> begins with
1.485 - * "<tt>java.</tt>".
1.486 - *
1.487 - * @see #defineClass(String, byte[], int, int, ProtectionDomain)
1.488 - *
1.489 - * @since 1.5
1.490 - */
1.491 - protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
1.492 - ProtectionDomain protectionDomain)
1.493 - throws ClassFormatError
1.494 - {
1.495 - int len = b.remaining();
1.496 -
1.497 - // Use byte[] if not a direct ByteBufer:
1.498 - if (!b.isDirect()) {
1.499 - if (b.hasArray()) {
1.500 - return defineClass(name, b.array(),
1.501 - b.position() + b.arrayOffset(), len,
1.502 - protectionDomain);
1.503 - } else {
1.504 - // no array, or read-only array
1.505 - byte[] tb = new byte[len];
1.506 - b.get(tb); // get bytes out of byte buffer.
1.507 - return defineClass(name, tb, 0, len, protectionDomain);
1.508 - }
1.509 - }
1.510 -
1.511 - protectionDomain = preDefineClass(name, protectionDomain);
1.512 -
1.513 - Class c = null;
1.514 - String source = defineClassSourceLocation(protectionDomain);
1.515 -
1.516 - try {
1.517 - c = defineClass2(name, b, b.position(), len, protectionDomain,
1.518 - source);
1.519 - } catch (ClassFormatError cfe) {
1.520 - byte[] tb = new byte[len];
1.521 - b.get(tb); // get bytes out of byte buffer.
1.522 - c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe,
1.523 - source);
1.524 - }
1.525 -
1.526 - postDefineClass(c, protectionDomain);
1.527 - return c;
1.528 - }
1.529 -
1.530 - private native Class defineClass0(String name, byte[] b, int off, int len,
1.531 - ProtectionDomain pd);
1.532 -
1.533 - private native Class defineClass1(String name, byte[] b, int off, int len,
1.534 - ProtectionDomain pd, String source);
1.535 -
1.536 - private native Class defineClass2(String name, java.nio.ByteBuffer b,
1.537 - int off, int len, ProtectionDomain pd,
1.538 - String source);
1.539 -
1.540 - // true if the name is null or has the potential to be a valid binary name
1.541 - private boolean checkName(String name) {
1.542 - if ((name == null) || (name.length() == 0))
1.543 - return true;
1.544 - if ((name.indexOf('/') != -1)
1.545 - || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
1.546 - return false;
1.547 - return true;
1.548 - }
1.549 -
1.550 - private void checkCerts(String name, CodeSource cs) {
1.551 - int i = name.lastIndexOf('.');
1.552 - String pname = (i == -1) ? "" : name.substring(0, i);
1.553 -
1.554 - Certificate[] certs = null;
1.555 - if (cs != null) {
1.556 - certs = cs.getCertificates();
1.557 - }
1.558 - Certificate[] pcerts = null;
1.559 - if (parallelLockMap == null) {
1.560 - synchronized (this) {
1.561 - pcerts = package2certs.get(pname);
1.562 - if (pcerts == null) {
1.563 - package2certs.put(pname, (certs == null? nocerts:certs));
1.564 - }
1.565 - }
1.566 - } else {
1.567 - pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).
1.568 - putIfAbsent(pname, (certs == null? nocerts:certs));
1.569 - }
1.570 - if (pcerts != null && !compareCerts(pcerts, certs)) {
1.571 - throw new SecurityException("class \""+ name +
1.572 - "\"'s signer information does not match signer information of other classes in the same package");
1.573 - }
1.574 - }
1.575 -
1.576 - /**
1.577 - * check to make sure the certs for the new class (certs) are the same as
1.578 - * the certs for the first class inserted in the package (pcerts)
1.579 - */
1.580 - private boolean compareCerts(Certificate[] pcerts,
1.581 - Certificate[] certs)
1.582 - {
1.583 - // certs can be null, indicating no certs.
1.584 - if ((certs == null) || (certs.length == 0)) {
1.585 - return pcerts.length == 0;
1.586 - }
1.587 -
1.588 - // the length must be the same at this point
1.589 - if (certs.length != pcerts.length)
1.590 - return false;
1.591 -
1.592 - // go through and make sure all the certs in one array
1.593 - // are in the other and vice-versa.
1.594 - boolean match;
1.595 - for (int i = 0; i < certs.length; i++) {
1.596 - match = false;
1.597 - for (int j = 0; j < pcerts.length; j++) {
1.598 - if (certs[i].equals(pcerts[j])) {
1.599 - match = true;
1.600 - break;
1.601 - }
1.602 - }
1.603 - if (!match) return false;
1.604 - }
1.605 -
1.606 - // now do the same for pcerts
1.607 - for (int i = 0; i < pcerts.length; i++) {
1.608 - match = false;
1.609 - for (int j = 0; j < certs.length; j++) {
1.610 - if (pcerts[i].equals(certs[j])) {
1.611 - match = true;
1.612 - break;
1.613 - }
1.614 - }
1.615 - if (!match) return false;
1.616 - }
1.617 -
1.618 - return true;
1.619 + throw new SecurityException();
1.620 }
1.621
1.622 /**
1.623 @@ -1012,57 +480,6 @@
1.624
1.625 private native void resolveClass0(Class c);
1.626
1.627 - /**
1.628 - * Finds a class with the specified <a href="#name">binary name</a>,
1.629 - * loading it if necessary.
1.630 - *
1.631 - * <p> This method loads the class through the system class loader (see
1.632 - * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned
1.633 - * might have more than one <tt>ClassLoader</tt> associated with it.
1.634 - * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
1.635 - * because most class loaders need to override just {@link
1.636 - * #findClass(String)}. </p>
1.637 - *
1.638 - * @param name
1.639 - * The <a href="#name">binary name</a> of the class
1.640 - *
1.641 - * @return The <tt>Class</tt> object for the specified <tt>name</tt>
1.642 - *
1.643 - * @throws ClassNotFoundException
1.644 - * If the class could not be found
1.645 - *
1.646 - * @see #ClassLoader(ClassLoader)
1.647 - * @see #getParent()
1.648 - */
1.649 - protected final Class<?> findSystemClass(String name)
1.650 - throws ClassNotFoundException
1.651 - {
1.652 - ClassLoader system = getSystemClassLoader();
1.653 - if (system == null) {
1.654 - if (!checkName(name))
1.655 - throw new ClassNotFoundException(name);
1.656 - Class cls = findBootstrapClass(name);
1.657 - if (cls == null) {
1.658 - throw new ClassNotFoundException(name);
1.659 - }
1.660 - return cls;
1.661 - }
1.662 - return system.loadClass(name);
1.663 - }
1.664 -
1.665 - /**
1.666 - * Returns a class loaded by the bootstrap class loader;
1.667 - * or return null if not found.
1.668 - */
1.669 - private Class findBootstrapClassOrNull(String name)
1.670 - {
1.671 - if (!checkName(name)) return null;
1.672 -
1.673 - return findBootstrapClass(name);
1.674 - }
1.675 -
1.676 - // return null if not found
1.677 - private native Class findBootstrapClass(String name);
1.678
1.679 /**
1.680 * Returns the class with the given <a href="#name">binary name</a> if this
1.681 @@ -1099,7 +516,8 @@
1.682 * @since 1.1
1.683 */
1.684 protected final void setSigners(Class<?> c, Object[] signers) {
1.685 - c.setSigners(signers);
1.686 + //c.setSigners(signers);
1.687 + throw new UnsupportedOperationException();
1.688 }
1.689
1.690
1.691 @@ -1175,7 +593,7 @@
1.692 }
1.693 tmp[1] = findResources(name);
1.694
1.695 - return new CompoundEnumeration<>(tmp);
1.696 + return new CompoundEnumeration(tmp);
1.697 }
1.698
1.699 /**
1.700 @@ -1212,7 +630,7 @@
1.701 * @since 1.2
1.702 */
1.703 protected Enumeration<URL> findResources(String name) throws IOException {
1.704 - return java.util.Collections.emptyEnumeration();
1.705 + return new CompoundEnumeration(new Enumeration[0]);
1.706 }
1.707
1.708 // index 0: java.lang.ClassLoader.class
1.709 @@ -1235,9 +653,9 @@
1.710 *
1.711 * @since 1.7
1.712 */
1.713 - protected static boolean registerAsParallelCapable() {
1.714 - return ParallelLoaders.register(getCaller(1));
1.715 - }
1.716 +// protected static boolean registerAsParallelCapable() {
1.717 +// return false;
1.718 +// }
1.719
1.720 /**
1.721 * Find a resource of the specified name from the search path used to load
1.722 @@ -1290,37 +708,6 @@
1.723 return system.getResources(name);
1.724 }
1.725
1.726 - /**
1.727 - * Find resources from the VM's built-in classloader.
1.728 - */
1.729 - private static URL getBootstrapResource(String name) {
1.730 - URLClassPath ucp = getBootstrapClassPath();
1.731 - Resource res = ucp.getResource(name);
1.732 - return res != null ? res.getURL() : null;
1.733 - }
1.734 -
1.735 - /**
1.736 - * Find resources from the VM's built-in classloader.
1.737 - */
1.738 - private static Enumeration<URL> getBootstrapResources(String name)
1.739 - throws IOException
1.740 - {
1.741 - final Enumeration<Resource> e =
1.742 - getBootstrapClassPath().getResources(name);
1.743 - return new Enumeration<URL> () {
1.744 - public URL nextElement() {
1.745 - return e.nextElement().getURL();
1.746 - }
1.747 - public boolean hasMoreElements() {
1.748 - return e.hasMoreElements();
1.749 - }
1.750 - };
1.751 - }
1.752 -
1.753 - // Returns the URLClassPath that is used for finding system resources.
1.754 - static URLClassPath getBootstrapClassPath() {
1.755 - return sun.misc.Launcher.getBootstrapClassPath();
1.756 - }
1.757
1.758
1.759 /**
1.760 @@ -1397,16 +784,7 @@
1.761 * @since 1.2
1.762 */
1.763 public final ClassLoader getParent() {
1.764 - if (parent == null)
1.765 - return null;
1.766 - SecurityManager sm = System.getSecurityManager();
1.767 - if (sm != null) {
1.768 - ClassLoader ccl = getCallerClassLoader();
1.769 - if (ccl != null && !isAncestor(ccl)) {
1.770 - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1.771 - }
1.772 - }
1.773 - return parent;
1.774 + throw new SecurityException();
1.775 }
1.776
1.777 /**
1.778 @@ -1465,48 +843,7 @@
1.779 * @revised 1.4
1.780 */
1.781 public static ClassLoader getSystemClassLoader() {
1.782 - initSystemClassLoader();
1.783 - if (scl == null) {
1.784 - return null;
1.785 - }
1.786 - SecurityManager sm = System.getSecurityManager();
1.787 - if (sm != null) {
1.788 - ClassLoader ccl = getCallerClassLoader();
1.789 - if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
1.790 - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1.791 - }
1.792 - }
1.793 - return scl;
1.794 - }
1.795 -
1.796 - private static synchronized void initSystemClassLoader() {
1.797 - if (!sclSet) {
1.798 - if (scl != null)
1.799 - throw new IllegalStateException("recursive invocation");
1.800 - sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
1.801 - if (l != null) {
1.802 - Throwable oops = null;
1.803 - scl = l.getClassLoader();
1.804 - try {
1.805 - scl = AccessController.doPrivileged(
1.806 - new SystemClassLoaderAction(scl));
1.807 - } catch (PrivilegedActionException pae) {
1.808 - oops = pae.getCause();
1.809 - if (oops instanceof InvocationTargetException) {
1.810 - oops = oops.getCause();
1.811 - }
1.812 - }
1.813 - if (oops != null) {
1.814 - if (oops instanceof Error) {
1.815 - throw (Error) oops;
1.816 - } else {
1.817 - // wrap the exception
1.818 - throw new Error(oops);
1.819 - }
1.820 - }
1.821 - }
1.822 - sclSet = true;
1.823 - }
1.824 + throw new SecurityException();
1.825 }
1.826
1.827 // Returns true if the specified class loader can be found in this class
1.828 @@ -1522,683 +859,54 @@
1.829 return false;
1.830 }
1.831
1.832 - // Returns the invoker's class loader, or null if none.
1.833 - // NOTE: This must always be invoked when there is exactly one intervening
1.834 - // frame from the core libraries on the stack between this method's
1.835 - // invocation and the desired invoker.
1.836 - static ClassLoader getCallerClassLoader() {
1.837 - // NOTE use of more generic Reflection.getCallerClass()
1.838 - Class caller = Reflection.getCallerClass(3);
1.839 - // This can be null if the VM is requesting it
1.840 - if (caller == null) {
1.841 - return null;
1.842 - }
1.843 - // Circumvent security check since this is package-private
1.844 - return caller.getClassLoader0();
1.845 + private boolean checkName(String name) {
1.846 + throw new UnsupportedOperationException();
1.847 }
1.848
1.849 - // The class loader for the system
1.850 - // @GuardedBy("ClassLoader.class")
1.851 - private static ClassLoader scl;
1.852 -
1.853 - // Set to true once the system class loader has been set
1.854 - // @GuardedBy("ClassLoader.class")
1.855 - private static boolean sclSet;
1.856 -
1.857 -
1.858 - // -- Package --
1.859 -
1.860 - /**
1.861 - * Defines a package by name in this <tt>ClassLoader</tt>. This allows
1.862 - * class loaders to define the packages for their classes. Packages must
1.863 - * be created before the class is defined, and package names must be
1.864 - * unique within a class loader and cannot be redefined or changed once
1.865 - * created. </p>
1.866 - *
1.867 - * @param name
1.868 - * The package name
1.869 - *
1.870 - * @param specTitle
1.871 - * The specification title
1.872 - *
1.873 - * @param specVersion
1.874 - * The specification version
1.875 - *
1.876 - * @param specVendor
1.877 - * The specification vendor
1.878 - *
1.879 - * @param implTitle
1.880 - * The implementation title
1.881 - *
1.882 - * @param implVersion
1.883 - * The implementation version
1.884 - *
1.885 - * @param implVendor
1.886 - * The implementation vendor
1.887 - *
1.888 - * @param sealBase
1.889 - * If not <tt>null</tt>, then this package is sealed with
1.890 - * respect to the given code source {@link java.net.URL
1.891 - * <tt>URL</tt>} object. Otherwise, the package is not sealed.
1.892 - *
1.893 - * @return The newly defined <tt>Package</tt> object
1.894 - *
1.895 - * @throws IllegalArgumentException
1.896 - * If package name duplicates an existing package either in this
1.897 - * class loader or one of its ancestors
1.898 - *
1.899 - * @since 1.2
1.900 - */
1.901 - protected Package definePackage(String name, String specTitle,
1.902 - String specVersion, String specVendor,
1.903 - String implTitle, String implVersion,
1.904 - String implVendor, URL sealBase)
1.905 - throws IllegalArgumentException
1.906 - {
1.907 - synchronized (packages) {
1.908 - Package pkg = getPackage(name);
1.909 - if (pkg != null) {
1.910 - throw new IllegalArgumentException(name);
1.911 - }
1.912 - pkg = new Package(name, specTitle, specVersion, specVendor,
1.913 - implTitle, implVersion, implVendor,
1.914 - sealBase, this);
1.915 - packages.put(name, pkg);
1.916 - return pkg;
1.917 - }
1.918 + private Class findBootstrapClassOrNull(String name) {
1.919 + throw new UnsupportedOperationException();
1.920 }
1.921
1.922 - /**
1.923 - * Returns a <tt>Package</tt> that has been defined by this class loader
1.924 - * or any of its ancestors. </p>
1.925 - *
1.926 - * @param name
1.927 - * The package name
1.928 - *
1.929 - * @return The <tt>Package</tt> corresponding to the given name, or
1.930 - * <tt>null</tt> if not found
1.931 - *
1.932 - * @since 1.2
1.933 - */
1.934 - protected Package getPackage(String name) {
1.935 - Package pkg;
1.936 - synchronized (packages) {
1.937 - pkg = packages.get(name);
1.938 + private static URL getBootstrapResource(String name) {
1.939 + throw new UnsupportedOperationException();
1.940 + }
1.941 +
1.942 + private static Enumeration<URL> getBootstrapResources(String name) {
1.943 + throw new UnsupportedOperationException();
1.944 + }
1.945 +
1.946 + private static class CompoundEnumeration implements Enumeration<URL> {
1.947 + private URL next;
1.948 + private int index;
1.949 + private final Enumeration[] arr;
1.950 +
1.951 + public CompoundEnumeration(Enumeration[] arr) {
1.952 + this.arr = arr;
1.953 + this.index = 0;
1.954 }
1.955 - if (pkg == null) {
1.956 - if (parent != null) {
1.957 - pkg = parent.getPackage(name);
1.958 - } else {
1.959 - pkg = Package.getSystemPackage(name);
1.960 - }
1.961 - if (pkg != null) {
1.962 - synchronized (packages) {
1.963 - Package pkg2 = packages.get(name);
1.964 - if (pkg2 == null) {
1.965 - packages.put(name, pkg);
1.966 - } else {
1.967 - pkg = pkg2;
1.968 +
1.969 + public boolean hasMoreElements() {
1.970 + if (next == null) {
1.971 + if (arr[index].hasMoreElements()) {
1.972 + next = (URL) arr[index].nextElement();
1.973 + } else {
1.974 + if (index < arr.length) {
1.975 + index++;
1.976 + return hasMoreElements();
1.977 }
1.978 }
1.979 }
1.980 - }
1.981 - return pkg;
1.982 - }
1.983 -
1.984 - /**
1.985 - * Returns all of the <tt>Packages</tt> defined by this class loader and
1.986 - * its ancestors. </p>
1.987 - *
1.988 - * @return The array of <tt>Package</tt> objects defined by this
1.989 - * <tt>ClassLoader</tt>
1.990 - *
1.991 - * @since 1.2
1.992 - */
1.993 - protected Package[] getPackages() {
1.994 - Map<String, Package> map;
1.995 - synchronized (packages) {
1.996 - map = new HashMap<>(packages);
1.997 - }
1.998 - Package[] pkgs;
1.999 - if (parent != null) {
1.1000 - pkgs = parent.getPackages();
1.1001 - } else {
1.1002 - pkgs = Package.getSystemPackages();
1.1003 - }
1.1004 - if (pkgs != null) {
1.1005 - for (int i = 0; i < pkgs.length; i++) {
1.1006 - String pkgName = pkgs[i].getName();
1.1007 - if (map.get(pkgName) == null) {
1.1008 - map.put(pkgName, pkgs[i]);
1.1009 - }
1.1010 - }
1.1011 - }
1.1012 - return map.values().toArray(new Package[map.size()]);
1.1013 - }
1.1014 -
1.1015 -
1.1016 - // -- Native library access --
1.1017 -
1.1018 - /**
1.1019 - * Returns the absolute path name of a native library. The VM invokes this
1.1020 - * method to locate the native libraries that belong to classes loaded with
1.1021 - * this class loader. If this method returns <tt>null</tt>, the VM
1.1022 - * searches the library along the path specified as the
1.1023 - * "<tt>java.library.path</tt>" property. </p>
1.1024 - *
1.1025 - * @param libname
1.1026 - * The library name
1.1027 - *
1.1028 - * @return The absolute path of the native library
1.1029 - *
1.1030 - * @see System#loadLibrary(String)
1.1031 - * @see System#mapLibraryName(String)
1.1032 - *
1.1033 - * @since 1.2
1.1034 - */
1.1035 - protected String findLibrary(String libname) {
1.1036 - return null;
1.1037 - }
1.1038 -
1.1039 - /**
1.1040 - * The inner class NativeLibrary denotes a loaded native library instance.
1.1041 - * Every classloader contains a vector of loaded native libraries in the
1.1042 - * private field <tt>nativeLibraries</tt>. The native libraries loaded
1.1043 - * into the system are entered into the <tt>systemNativeLibraries</tt>
1.1044 - * vector.
1.1045 - *
1.1046 - * <p> Every native library requires a particular version of JNI. This is
1.1047 - * denoted by the private <tt>jniVersion</tt> field. This field is set by
1.1048 - * the VM when it loads the library, and used by the VM to pass the correct
1.1049 - * version of JNI to the native methods. </p>
1.1050 - *
1.1051 - * @see ClassLoader
1.1052 - * @since 1.2
1.1053 - */
1.1054 - static class NativeLibrary {
1.1055 - // opaque handle to native library, used in native code.
1.1056 - long handle;
1.1057 - // the version of JNI environment the native library requires.
1.1058 - private int jniVersion;
1.1059 - // the class from which the library is loaded, also indicates
1.1060 - // the loader this native library belongs.
1.1061 - private Class fromClass;
1.1062 - // the canonicalized name of the native library.
1.1063 - String name;
1.1064 -
1.1065 - native void load(String name);
1.1066 - native long find(String name);
1.1067 - native void unload();
1.1068 -
1.1069 - public NativeLibrary(Class fromClass, String name) {
1.1070 - this.name = name;
1.1071 - this.fromClass = fromClass;
1.1072 + return next != null;
1.1073 }
1.1074
1.1075 - protected void finalize() {
1.1076 - synchronized (loadedLibraryNames) {
1.1077 - if (fromClass.getClassLoader() != null && handle != 0) {
1.1078 - /* remove the native library name */
1.1079 - int size = loadedLibraryNames.size();
1.1080 - for (int i = 0; i < size; i++) {
1.1081 - if (name.equals(loadedLibraryNames.elementAt(i))) {
1.1082 - loadedLibraryNames.removeElementAt(i);
1.1083 - break;
1.1084 - }
1.1085 - }
1.1086 - /* unload the library. */
1.1087 - ClassLoader.nativeLibraryContext.push(this);
1.1088 - try {
1.1089 - unload();
1.1090 - } finally {
1.1091 - ClassLoader.nativeLibraryContext.pop();
1.1092 - }
1.1093 - }
1.1094 + public URL nextElement() {
1.1095 + if (!hasMoreElements()) {
1.1096 + throw new NoSuchElementException();
1.1097 }
1.1098 + URL r = next;
1.1099 + next = null;
1.1100 + return r;
1.1101 }
1.1102 - // Invoked in the VM to determine the context class in
1.1103 - // JNI_Load/JNI_Unload
1.1104 - static Class getFromClass() {
1.1105 - return ClassLoader.nativeLibraryContext.peek().fromClass;
1.1106 - }
1.1107 - }
1.1108 -
1.1109 - // All native library names we've loaded.
1.1110 - private static Vector<String> loadedLibraryNames = new Vector<>();
1.1111 -
1.1112 - // Native libraries belonging to system classes.
1.1113 - private static Vector<NativeLibrary> systemNativeLibraries
1.1114 - = new Vector<>();
1.1115 -
1.1116 - // Native libraries associated with the class loader.
1.1117 - private Vector<NativeLibrary> nativeLibraries = new Vector<>();
1.1118 -
1.1119 - // native libraries being loaded/unloaded.
1.1120 - private static Stack<NativeLibrary> nativeLibraryContext = new Stack<>();
1.1121 -
1.1122 - // The paths searched for libraries
1.1123 - private static String usr_paths[];
1.1124 - private static String sys_paths[];
1.1125 -
1.1126 - private static String[] initializePath(String propname) {
1.1127 - String ldpath = System.getProperty(propname, "");
1.1128 - String ps = File.pathSeparator;
1.1129 - int ldlen = ldpath.length();
1.1130 - int i, j, n;
1.1131 - // Count the separators in the path
1.1132 - i = ldpath.indexOf(ps);
1.1133 - n = 0;
1.1134 - while (i >= 0) {
1.1135 - n++;
1.1136 - i = ldpath.indexOf(ps, i + 1);
1.1137 - }
1.1138 -
1.1139 - // allocate the array of paths - n :'s = n + 1 path elements
1.1140 - String[] paths = new String[n + 1];
1.1141 -
1.1142 - // Fill the array with paths from the ldpath
1.1143 - n = i = 0;
1.1144 - j = ldpath.indexOf(ps);
1.1145 - while (j >= 0) {
1.1146 - if (j - i > 0) {
1.1147 - paths[n++] = ldpath.substring(i, j);
1.1148 - } else if (j - i == 0) {
1.1149 - paths[n++] = ".";
1.1150 - }
1.1151 - i = j + 1;
1.1152 - j = ldpath.indexOf(ps, i);
1.1153 - }
1.1154 - paths[n] = ldpath.substring(i, ldlen);
1.1155 - return paths;
1.1156 - }
1.1157 -
1.1158 - // Invoked in the java.lang.Runtime class to implement load and loadLibrary.
1.1159 - static void loadLibrary(Class fromClass, String name,
1.1160 - boolean isAbsolute) {
1.1161 - ClassLoader loader =
1.1162 - (fromClass == null) ? null : fromClass.getClassLoader();
1.1163 - if (sys_paths == null) {
1.1164 - usr_paths = initializePath("java.library.path");
1.1165 - sys_paths = initializePath("sun.boot.library.path");
1.1166 - }
1.1167 - if (isAbsolute) {
1.1168 - if (loadLibrary0(fromClass, new File(name))) {
1.1169 - return;
1.1170 - }
1.1171 - throw new UnsatisfiedLinkError("Can't load library: " + name);
1.1172 - }
1.1173 - if (loader != null) {
1.1174 - String libfilename = loader.findLibrary(name);
1.1175 - if (libfilename != null) {
1.1176 - File libfile = new File(libfilename);
1.1177 - if (!libfile.isAbsolute()) {
1.1178 - throw new UnsatisfiedLinkError(
1.1179 - "ClassLoader.findLibrary failed to return an absolute path: " + libfilename);
1.1180 - }
1.1181 - if (loadLibrary0(fromClass, libfile)) {
1.1182 - return;
1.1183 - }
1.1184 - throw new UnsatisfiedLinkError("Can't load " + libfilename);
1.1185 - }
1.1186 - }
1.1187 - for (int i = 0 ; i < sys_paths.length ; i++) {
1.1188 - File libfile = new File(sys_paths[i], System.mapLibraryName(name));
1.1189 - if (loadLibrary0(fromClass, libfile)) {
1.1190 - return;
1.1191 - }
1.1192 - }
1.1193 - if (loader != null) {
1.1194 - for (int i = 0 ; i < usr_paths.length ; i++) {
1.1195 - File libfile = new File(usr_paths[i],
1.1196 - System.mapLibraryName(name));
1.1197 - if (loadLibrary0(fromClass, libfile)) {
1.1198 - return;
1.1199 - }
1.1200 - }
1.1201 - }
1.1202 - // Oops, it failed
1.1203 - throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
1.1204 - }
1.1205 -
1.1206 - private static boolean loadLibrary0(Class fromClass, final File file) {
1.1207 - boolean exists = AccessController.doPrivileged(
1.1208 - new PrivilegedAction<Object>() {
1.1209 - public Object run() {
1.1210 - return file.exists() ? Boolean.TRUE : null;
1.1211 - }})
1.1212 - != null;
1.1213 - if (!exists) {
1.1214 - return false;
1.1215 - }
1.1216 - String name;
1.1217 - try {
1.1218 - name = file.getCanonicalPath();
1.1219 - } catch (IOException e) {
1.1220 - return false;
1.1221 - }
1.1222 - ClassLoader loader =
1.1223 - (fromClass == null) ? null : fromClass.getClassLoader();
1.1224 - Vector<NativeLibrary> libs =
1.1225 - loader != null ? loader.nativeLibraries : systemNativeLibraries;
1.1226 - synchronized (libs) {
1.1227 - int size = libs.size();
1.1228 - for (int i = 0; i < size; i++) {
1.1229 - NativeLibrary lib = libs.elementAt(i);
1.1230 - if (name.equals(lib.name)) {
1.1231 - return true;
1.1232 - }
1.1233 - }
1.1234 -
1.1235 - synchronized (loadedLibraryNames) {
1.1236 - if (loadedLibraryNames.contains(name)) {
1.1237 - throw new UnsatisfiedLinkError
1.1238 - ("Native Library " +
1.1239 - name +
1.1240 - " already loaded in another classloader");
1.1241 - }
1.1242 - /* If the library is being loaded (must be by the same thread,
1.1243 - * because Runtime.load and Runtime.loadLibrary are
1.1244 - * synchronous). The reason is can occur is that the JNI_OnLoad
1.1245 - * function can cause another loadLibrary invocation.
1.1246 - *
1.1247 - * Thus we can use a static stack to hold the list of libraries
1.1248 - * we are loading.
1.1249 - *
1.1250 - * If there is a pending load operation for the library, we
1.1251 - * immediately return success; otherwise, we raise
1.1252 - * UnsatisfiedLinkError.
1.1253 - */
1.1254 - int n = nativeLibraryContext.size();
1.1255 - for (int i = 0; i < n; i++) {
1.1256 - NativeLibrary lib = nativeLibraryContext.elementAt(i);
1.1257 - if (name.equals(lib.name)) {
1.1258 - if (loader == lib.fromClass.getClassLoader()) {
1.1259 - return true;
1.1260 - } else {
1.1261 - throw new UnsatisfiedLinkError
1.1262 - ("Native Library " +
1.1263 - name +
1.1264 - " is being loaded in another classloader");
1.1265 - }
1.1266 - }
1.1267 - }
1.1268 - NativeLibrary lib = new NativeLibrary(fromClass, name);
1.1269 - nativeLibraryContext.push(lib);
1.1270 - try {
1.1271 - lib.load(name);
1.1272 - } finally {
1.1273 - nativeLibraryContext.pop();
1.1274 - }
1.1275 - if (lib.handle != 0) {
1.1276 - loadedLibraryNames.addElement(name);
1.1277 - libs.addElement(lib);
1.1278 - return true;
1.1279 - }
1.1280 - return false;
1.1281 - }
1.1282 - }
1.1283 - }
1.1284 -
1.1285 - // Invoked in the VM class linking code.
1.1286 - static long findNative(ClassLoader loader, String name) {
1.1287 - Vector<NativeLibrary> libs =
1.1288 - loader != null ? loader.nativeLibraries : systemNativeLibraries;
1.1289 - synchronized (libs) {
1.1290 - int size = libs.size();
1.1291 - for (int i = 0; i < size; i++) {
1.1292 - NativeLibrary lib = libs.elementAt(i);
1.1293 - long entry = lib.find(name);
1.1294 - if (entry != 0)
1.1295 - return entry;
1.1296 - }
1.1297 - }
1.1298 - return 0;
1.1299 - }
1.1300 -
1.1301 -
1.1302 - // -- Assertion management --
1.1303 -
1.1304 - final Object assertionLock;
1.1305 -
1.1306 - // The default toggle for assertion checking.
1.1307 - // @GuardedBy("assertionLock")
1.1308 - private boolean defaultAssertionStatus = false;
1.1309 -
1.1310 - // Maps String packageName to Boolean package default assertion status Note
1.1311 - // that the default package is placed under a null map key. If this field
1.1312 - // is null then we are delegating assertion status queries to the VM, i.e.,
1.1313 - // none of this ClassLoader's assertion status modification methods have
1.1314 - // been invoked.
1.1315 - // @GuardedBy("assertionLock")
1.1316 - private Map<String, Boolean> packageAssertionStatus = null;
1.1317 -
1.1318 - // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
1.1319 - // field is null then we are delegating assertion status queries to the VM,
1.1320 - // i.e., none of this ClassLoader's assertion status modification methods
1.1321 - // have been invoked.
1.1322 - // @GuardedBy("assertionLock")
1.1323 - Map<String, Boolean> classAssertionStatus = null;
1.1324 -
1.1325 - /**
1.1326 - * Sets the default assertion status for this class loader. This setting
1.1327 - * determines whether classes loaded by this class loader and initialized
1.1328 - * in the future will have assertions enabled or disabled by default.
1.1329 - * This setting may be overridden on a per-package or per-class basis by
1.1330 - * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
1.1331 - * #setClassAssertionStatus(String, boolean)}. </p>
1.1332 - *
1.1333 - * @param enabled
1.1334 - * <tt>true</tt> if classes loaded by this class loader will
1.1335 - * henceforth have assertions enabled by default, <tt>false</tt>
1.1336 - * if they will have assertions disabled by default.
1.1337 - *
1.1338 - * @since 1.4
1.1339 - */
1.1340 - public void setDefaultAssertionStatus(boolean enabled) {
1.1341 - synchronized (assertionLock) {
1.1342 - if (classAssertionStatus == null)
1.1343 - initializeJavaAssertionMaps();
1.1344 -
1.1345 - defaultAssertionStatus = enabled;
1.1346 - }
1.1347 - }
1.1348 -
1.1349 - /**
1.1350 - * Sets the package default assertion status for the named package. The
1.1351 - * package default assertion status determines the assertion status for
1.1352 - * classes initialized in the future that belong to the named package or
1.1353 - * any of its "subpackages".
1.1354 - *
1.1355 - * <p> A subpackage of a package named p is any package whose name begins
1.1356 - * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a
1.1357 - * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
1.1358 - * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
1.1359 - *
1.1360 - * <p> In the event that multiple package defaults apply to a given class,
1.1361 - * the package default pertaining to the most specific package takes
1.1362 - * precedence over the others. For example, if <tt>javax.lang</tt> and
1.1363 - * <tt>javax.lang.reflect</tt> both have package defaults associated with
1.1364 - * them, the latter package default applies to classes in
1.1365 - * <tt>javax.lang.reflect</tt>.
1.1366 - *
1.1367 - * <p> Package defaults take precedence over the class loader's default
1.1368 - * assertion status, and may be overridden on a per-class basis by invoking
1.1369 - * {@link #setClassAssertionStatus(String, boolean)}. </p>
1.1370 - *
1.1371 - * @param packageName
1.1372 - * The name of the package whose package default assertion status
1.1373 - * is to be set. A <tt>null</tt> value indicates the unnamed
1.1374 - * package that is "current"
1.1375 - * (see section 7.4.2 of
1.1376 - * <cite>The Java™ Language Specification</cite>.)
1.1377 - *
1.1378 - * @param enabled
1.1379 - * <tt>true</tt> if classes loaded by this classloader and
1.1380 - * belonging to the named package or any of its subpackages will
1.1381 - * have assertions enabled by default, <tt>false</tt> if they will
1.1382 - * have assertions disabled by default.
1.1383 - *
1.1384 - * @since 1.4
1.1385 - */
1.1386 - public void setPackageAssertionStatus(String packageName,
1.1387 - boolean enabled) {
1.1388 - synchronized (assertionLock) {
1.1389 - if (packageAssertionStatus == null)
1.1390 - initializeJavaAssertionMaps();
1.1391 -
1.1392 - packageAssertionStatus.put(packageName, enabled);
1.1393 - }
1.1394 - }
1.1395 -
1.1396 - /**
1.1397 - * Sets the desired assertion status for the named top-level class in this
1.1398 - * class loader and any nested classes contained therein. This setting
1.1399 - * takes precedence over the class loader's default assertion status, and
1.1400 - * over any applicable per-package default. This method has no effect if
1.1401 - * the named class has already been initialized. (Once a class is
1.1402 - * initialized, its assertion status cannot change.)
1.1403 - *
1.1404 - * <p> If the named class is not a top-level class, this invocation will
1.1405 - * have no effect on the actual assertion status of any class. </p>
1.1406 - *
1.1407 - * @param className
1.1408 - * The fully qualified class name of the top-level class whose
1.1409 - * assertion status is to be set.
1.1410 - *
1.1411 - * @param enabled
1.1412 - * <tt>true</tt> if the named class is to have assertions
1.1413 - * enabled when (and if) it is initialized, <tt>false</tt> if the
1.1414 - * class is to have assertions disabled.
1.1415 - *
1.1416 - * @since 1.4
1.1417 - */
1.1418 - public void setClassAssertionStatus(String className, boolean enabled) {
1.1419 - synchronized (assertionLock) {
1.1420 - if (classAssertionStatus == null)
1.1421 - initializeJavaAssertionMaps();
1.1422 -
1.1423 - classAssertionStatus.put(className, enabled);
1.1424 - }
1.1425 - }
1.1426 -
1.1427 - /**
1.1428 - * Sets the default assertion status for this class loader to
1.1429 - * <tt>false</tt> and discards any package defaults or class assertion
1.1430 - * status settings associated with the class loader. This method is
1.1431 - * provided so that class loaders can be made to ignore any command line or
1.1432 - * persistent assertion status settings and "start with a clean slate."
1.1433 - * </p>
1.1434 - *
1.1435 - * @since 1.4
1.1436 - */
1.1437 - public void clearAssertionStatus() {
1.1438 - /*
1.1439 - * Whether or not "Java assertion maps" are initialized, set
1.1440 - * them to empty maps, effectively ignoring any present settings.
1.1441 - */
1.1442 - synchronized (assertionLock) {
1.1443 - classAssertionStatus = new HashMap<>();
1.1444 - packageAssertionStatus = new HashMap<>();
1.1445 - defaultAssertionStatus = false;
1.1446 - }
1.1447 - }
1.1448 -
1.1449 - /**
1.1450 - * Returns the assertion status that would be assigned to the specified
1.1451 - * class if it were to be initialized at the time this method is invoked.
1.1452 - * If the named class has had its assertion status set, the most recent
1.1453 - * setting will be returned; otherwise, if any package default assertion
1.1454 - * status pertains to this class, the most recent setting for the most
1.1455 - * specific pertinent package default assertion status is returned;
1.1456 - * otherwise, this class loader's default assertion status is returned.
1.1457 - * </p>
1.1458 - *
1.1459 - * @param className
1.1460 - * The fully qualified class name of the class whose desired
1.1461 - * assertion status is being queried.
1.1462 - *
1.1463 - * @return The desired assertion status of the specified class.
1.1464 - *
1.1465 - * @see #setClassAssertionStatus(String, boolean)
1.1466 - * @see #setPackageAssertionStatus(String, boolean)
1.1467 - * @see #setDefaultAssertionStatus(boolean)
1.1468 - *
1.1469 - * @since 1.4
1.1470 - */
1.1471 - boolean desiredAssertionStatus(String className) {
1.1472 - synchronized (assertionLock) {
1.1473 - // assert classAssertionStatus != null;
1.1474 - // assert packageAssertionStatus != null;
1.1475 -
1.1476 - // Check for a class entry
1.1477 - Boolean result = classAssertionStatus.get(className);
1.1478 - if (result != null)
1.1479 - return result.booleanValue();
1.1480 -
1.1481 - // Check for most specific package entry
1.1482 - int dotIndex = className.lastIndexOf(".");
1.1483 - if (dotIndex < 0) { // default package
1.1484 - result = packageAssertionStatus.get(null);
1.1485 - if (result != null)
1.1486 - return result.booleanValue();
1.1487 - }
1.1488 - while(dotIndex > 0) {
1.1489 - className = className.substring(0, dotIndex);
1.1490 - result = packageAssertionStatus.get(className);
1.1491 - if (result != null)
1.1492 - return result.booleanValue();
1.1493 - dotIndex = className.lastIndexOf(".", dotIndex-1);
1.1494 - }
1.1495 -
1.1496 - // Return the classloader default
1.1497 - return defaultAssertionStatus;
1.1498 - }
1.1499 - }
1.1500 -
1.1501 - // Set up the assertions with information provided by the VM.
1.1502 - // Note: Should only be called inside a synchronized block
1.1503 - private void initializeJavaAssertionMaps() {
1.1504 - // assert Thread.holdsLock(assertionLock);
1.1505 -
1.1506 - classAssertionStatus = new HashMap<>();
1.1507 - packageAssertionStatus = new HashMap<>();
1.1508 - AssertionStatusDirectives directives = retrieveDirectives();
1.1509 -
1.1510 - for(int i = 0; i < directives.classes.length; i++)
1.1511 - classAssertionStatus.put(directives.classes[i],
1.1512 - directives.classEnabled[i]);
1.1513 -
1.1514 - for(int i = 0; i < directives.packages.length; i++)
1.1515 - packageAssertionStatus.put(directives.packages[i],
1.1516 - directives.packageEnabled[i]);
1.1517 -
1.1518 - defaultAssertionStatus = directives.deflt;
1.1519 - }
1.1520 -
1.1521 - // Retrieves the assertion directives from the VM.
1.1522 - private static native AssertionStatusDirectives retrieveDirectives();
1.1523 -}
1.1524 -
1.1525 -
1.1526 -class SystemClassLoaderAction
1.1527 - implements PrivilegedExceptionAction<ClassLoader> {
1.1528 - private ClassLoader parent;
1.1529 -
1.1530 - SystemClassLoaderAction(ClassLoader parent) {
1.1531 - this.parent = parent;
1.1532 - }
1.1533 -
1.1534 - public ClassLoader run() throws Exception {
1.1535 - String cls = System.getProperty("java.system.class.loader");
1.1536 - if (cls == null) {
1.1537 - return parent;
1.1538 - }
1.1539 -
1.1540 - Constructor ctor = Class.forName(cls, true, parent)
1.1541 - .getDeclaredConstructor(new Class[] { ClassLoader.class });
1.1542 - ClassLoader sys = (ClassLoader) ctor.newInstance(
1.1543 - new Object[] { parent });
1.1544 - Thread.currentThread().setContextClassLoader(sys);
1.1545 - return sys;
1.1546 +
1.1547 }
1.1548 }