230 synchronized (loaderTypes) {
231 return loaderTypes.contains(c);
232 }
233 }
234 }
235
236 // Maps class name to the corresponding lock object when the current
237 // class loader is parallel capable.
238 // Note: VM also uses this field to decide if the current class loader
239 // is parallel capable and the appropriate lock object for class loading.
240 private final ConcurrentHashMap<String, Object> parallelLockMap;
241
242 // Hashtable that maps packages to certs
243 private final Map <String, Certificate[]> package2certs;
244
245 // Shared among all packages with unsigned classes
246 private static final Certificate[] nocerts = new Certificate[0];
247
248 // The classes loaded by this class loader. The only purpose of this table
249 // is to keep the classes from being GC'ed until the loader is GC'ed.
250 private final Vector<Class<?>> classes = new Vector<Class<?>>();
251
252 // The "default" domain. Set as the default ProtectionDomain on newly
253 // created classes.
254 private final ProtectionDomain defaultDomain =
255 new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
256 null, this, null);
257
258 // The initiating protection domains for all classes loaded by this loader
259 private final Set<ProtectionDomain> domains;
260
261 // Invoked by the VM to record every loaded class with this loader.
262 void addClass(Class c) {
263 classes.addElement(c);
264 }
265
266 // The packages defined in this class loader. Each package name is mapped
267 // to its corresponding Package object.
268 // @GuardedBy("itself")
269 private final HashMap<String, Package> packages =
270 new HashMap<String, Package>();
271
272 private static Void checkCreateClassLoader() {
273 SecurityManager security = System.getSecurityManager();
274 if (security != null) {
275 security.checkCreateClassLoader();
276 }
277 return null;
278 }
279
280 private ClassLoader(Void unused, ClassLoader parent) {
281 this.parent = parent;
282 if (ParallelLoaders.isRegistered(this.getClass())) {
283 parallelLockMap = new ConcurrentHashMap<String, Object>();
284 package2certs = new ConcurrentHashMap<String, Certificate[]>();
285 domains =
286 Collections.synchronizedSet(new HashSet<ProtectionDomain>());
287 assertionLock = new Object();
288 } else {
289 // no finer-grained lock; lock on the classloader instance
290 parallelLockMap = null;
291 package2certs = new Hashtable<String, Certificate[]>();
292 domains = new HashSet<ProtectionDomain>();
293 assertionLock = this;
294 }
295 }
296
297 /**
298 * Creates a new class loader using the specified parent class loader for
299 * delegation.
300 *
301 * <p> If there is a security manager, its {@link
302 * SecurityManager#checkCreateClassLoader()
303 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
304 * a security exception. </p>
305 *
306 * @param parent
307 * The parent class loader
308 *
309 * @throws SecurityException
310 * If a security manager exists and its
311 * <tt>checkCreateClassLoader</tt> method doesn't allow creation
312 * of a new class loader.
1165 * the resource. If no resources could be found, the enumeration
1166 * will be empty. Resources that the class loader doesn't have
1167 * access to will not be in the enumeration.
1168 *
1169 * @throws IOException
1170 * If I/O errors occur
1171 *
1172 * @see #findResources(String)
1173 *
1174 * @since 1.2
1175 */
1176 public Enumeration<URL> getResources(String name) throws IOException {
1177 Enumeration[] tmp = new Enumeration[2];
1178 if (parent != null) {
1179 tmp[0] = parent.getResources(name);
1180 } else {
1181 tmp[0] = getBootstrapResources(name);
1182 }
1183 tmp[1] = findResources(name);
1184
1185 return new CompoundEnumeration<URL>(tmp);
1186 }
1187
1188 /**
1189 * Finds the resource with the given name. Class loader implementations
1190 * should override this method to specify where to find resources. </p>
1191 *
1192 * @param name
1193 * The resource name
1194 *
1195 * @return A <tt>URL</tt> object for reading the resource, or
1196 * <tt>null</tt> if the resource could not be found
1197 *
1198 * @since 1.2
1199 */
1200 protected URL findResource(String name) {
1201 return null;
1202 }
1203
1204 /**
1205 * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
1640 if (pkg != null) {
1641 packages.put(name, pkg);
1642 }
1643 }
1644 return pkg;
1645 }
1646 }
1647
1648 /**
1649 * Returns all of the <tt>Packages</tt> defined by this class loader and
1650 * its ancestors. </p>
1651 *
1652 * @return The array of <tt>Package</tt> objects defined by this
1653 * <tt>ClassLoader</tt>
1654 *
1655 * @since 1.2
1656 */
1657 protected Package[] getPackages() {
1658 Map<String, Package> map;
1659 synchronized (packages) {
1660 map = new HashMap<String, Package>(packages);
1661 }
1662 Package[] pkgs;
1663 if (parent != null) {
1664 pkgs = parent.getPackages();
1665 } else {
1666 pkgs = Package.getSystemPackages();
1667 }
1668 if (pkgs != null) {
1669 for (int i = 0; i < pkgs.length; i++) {
1670 String pkgName = pkgs[i].getName();
1671 if (map.get(pkgName) == null) {
1672 map.put(pkgName, pkgs[i]);
1673 }
1674 }
1675 }
1676 return map.values().toArray(new Package[map.size()]);
1677 }
1678
1679
1680 // -- Native library access --
1748 }
1749 /* unload the library. */
1750 ClassLoader.nativeLibraryContext.push(this);
1751 try {
1752 unload();
1753 } finally {
1754 ClassLoader.nativeLibraryContext.pop();
1755 }
1756 }
1757 }
1758 }
1759 // Invoked in the VM to determine the context class in
1760 // JNI_Load/JNI_Unload
1761 static Class getFromClass() {
1762 return ClassLoader.nativeLibraryContext.peek().fromClass;
1763 }
1764 }
1765
1766 // All native library names we've loaded.
1767 private static Vector<String> loadedLibraryNames
1768 = new Vector<String>();
1769
1770 // Native libraries belonging to system classes.
1771 private static Vector<NativeLibrary> systemNativeLibraries
1772 = new Vector<NativeLibrary>();
1773
1774 // Native libraries associated with the class loader.
1775 private Vector<NativeLibrary> nativeLibraries
1776 = new Vector<NativeLibrary>();
1777
1778 // native libraries being loaded/unloaded.
1779 private static Stack<NativeLibrary> nativeLibraryContext
1780 = new Stack<NativeLibrary>();
1781
1782 // The paths searched for libraries
1783 private static String usr_paths[];
1784 private static String sys_paths[];
1785
1786 private static String[] initializePath(String propname) {
1787 String ldpath = System.getProperty(propname, "");
1788 String ps = File.pathSeparator;
1789 int ldlen = ldpath.length();
1790 int i, j, n;
1791 // Count the separators in the path
1792 i = ldpath.indexOf(ps);
1793 n = 0;
1794 while (i >= 0) {
1795 n++;
1796 i = ldpath.indexOf(ps, i + 1);
1797 }
1798
1799 // allocate the array of paths - n :'s = n + 1 path elements
1800 String[] paths = new String[n + 1];
2084 classAssertionStatus.put(className, enabled);
2085 }
2086 }
2087
2088 /**
2089 * Sets the default assertion status for this class loader to
2090 * <tt>false</tt> and discards any package defaults or class assertion
2091 * status settings associated with the class loader. This method is
2092 * provided so that class loaders can be made to ignore any command line or
2093 * persistent assertion status settings and "start with a clean slate."
2094 * </p>
2095 *
2096 * @since 1.4
2097 */
2098 public void clearAssertionStatus() {
2099 /*
2100 * Whether or not "Java assertion maps" are initialized, set
2101 * them to empty maps, effectively ignoring any present settings.
2102 */
2103 synchronized (assertionLock) {
2104 classAssertionStatus = new HashMap<String, Boolean>();
2105 packageAssertionStatus = new HashMap<String, Boolean>();
2106 defaultAssertionStatus = false;
2107 }
2108 }
2109
2110 /**
2111 * Returns the assertion status that would be assigned to the specified
2112 * class if it were to be initialized at the time this method is invoked.
2113 * If the named class has had its assertion status set, the most recent
2114 * setting will be returned; otherwise, if any package default assertion
2115 * status pertains to this class, the most recent setting for the most
2116 * specific pertinent package default assertion status is returned;
2117 * otherwise, this class loader's default assertion status is returned.
2118 * </p>
2119 *
2120 * @param className
2121 * The fully qualified class name of the class whose desired
2122 * assertion status is being queried.
2123 *
2124 * @return The desired assertion status of the specified class.
2125 *
2147 return result.booleanValue();
2148 }
2149 while(dotIndex > 0) {
2150 className = className.substring(0, dotIndex);
2151 result = packageAssertionStatus.get(className);
2152 if (result != null)
2153 return result.booleanValue();
2154 dotIndex = className.lastIndexOf(".", dotIndex-1);
2155 }
2156
2157 // Return the classloader default
2158 return defaultAssertionStatus;
2159 }
2160 }
2161
2162 // Set up the assertions with information provided by the VM.
2163 // Note: Should only be called inside a synchronized block
2164 private void initializeJavaAssertionMaps() {
2165 // assert Thread.holdsLock(assertionLock);
2166
2167 classAssertionStatus = new HashMap<String, Boolean>();
2168 packageAssertionStatus = new HashMap<String, Boolean>();
2169 AssertionStatusDirectives directives = retrieveDirectives();
2170
2171 for(int i = 0; i < directives.classes.length; i++)
2172 classAssertionStatus.put(directives.classes[i],
2173 directives.classEnabled[i]);
2174
2175 for(int i = 0; i < directives.packages.length; i++)
2176 packageAssertionStatus.put(directives.packages[i],
2177 directives.packageEnabled[i]);
2178
2179 defaultAssertionStatus = directives.deflt;
2180 }
2181
2182 // Retrieves the assertion directives from the VM.
2183 private static native AssertionStatusDirectives retrieveDirectives();
2184 }
2185
2186
2187 class SystemClassLoaderAction
2188 implements PrivilegedExceptionAction<ClassLoader> {
|
230 synchronized (loaderTypes) {
231 return loaderTypes.contains(c);
232 }
233 }
234 }
235
236 // Maps class name to the corresponding lock object when the current
237 // class loader is parallel capable.
238 // Note: VM also uses this field to decide if the current class loader
239 // is parallel capable and the appropriate lock object for class loading.
240 private final ConcurrentHashMap<String, Object> parallelLockMap;
241
242 // Hashtable that maps packages to certs
243 private final Map <String, Certificate[]> package2certs;
244
245 // Shared among all packages with unsigned classes
246 private static final Certificate[] nocerts = new Certificate[0];
247
248 // The classes loaded by this class loader. The only purpose of this table
249 // is to keep the classes from being GC'ed until the loader is GC'ed.
250 private final Vector<Class<?>> classes = new Vector<>();
251
252 // The "default" domain. Set as the default ProtectionDomain on newly
253 // created classes.
254 private final ProtectionDomain defaultDomain =
255 new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
256 null, this, null);
257
258 // The initiating protection domains for all classes loaded by this loader
259 private final Set<ProtectionDomain> domains;
260
261 // Invoked by the VM to record every loaded class with this loader.
262 void addClass(Class c) {
263 classes.addElement(c);
264 }
265
266 // The packages defined in this class loader. Each package name is mapped
267 // to its corresponding Package object.
268 // @GuardedBy("itself")
269 private final HashMap<String, Package> packages =
270 new HashMap<>();
271
272 private static Void checkCreateClassLoader() {
273 SecurityManager security = System.getSecurityManager();
274 if (security != null) {
275 security.checkCreateClassLoader();
276 }
277 return null;
278 }
279
280 private ClassLoader(Void unused, ClassLoader parent) {
281 this.parent = parent;
282 if (ParallelLoaders.isRegistered(this.getClass())) {
283 parallelLockMap = new ConcurrentHashMap<>();
284 package2certs = new ConcurrentHashMap<>();
285 domains =
286 Collections.synchronizedSet(new HashSet<ProtectionDomain>());
287 assertionLock = new Object();
288 } else {
289 // no finer-grained lock; lock on the classloader instance
290 parallelLockMap = null;
291 package2certs = new Hashtable<>();
292 domains = new HashSet<>();
293 assertionLock = this;
294 }
295 }
296
297 /**
298 * Creates a new class loader using the specified parent class loader for
299 * delegation.
300 *
301 * <p> If there is a security manager, its {@link
302 * SecurityManager#checkCreateClassLoader()
303 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
304 * a security exception. </p>
305 *
306 * @param parent
307 * The parent class loader
308 *
309 * @throws SecurityException
310 * If a security manager exists and its
311 * <tt>checkCreateClassLoader</tt> method doesn't allow creation
312 * of a new class loader.
1165 * the resource. If no resources could be found, the enumeration
1166 * will be empty. Resources that the class loader doesn't have
1167 * access to will not be in the enumeration.
1168 *
1169 * @throws IOException
1170 * If I/O errors occur
1171 *
1172 * @see #findResources(String)
1173 *
1174 * @since 1.2
1175 */
1176 public Enumeration<URL> getResources(String name) throws IOException {
1177 Enumeration[] tmp = new Enumeration[2];
1178 if (parent != null) {
1179 tmp[0] = parent.getResources(name);
1180 } else {
1181 tmp[0] = getBootstrapResources(name);
1182 }
1183 tmp[1] = findResources(name);
1184
1185 return new CompoundEnumeration<>(tmp);
1186 }
1187
1188 /**
1189 * Finds the resource with the given name. Class loader implementations
1190 * should override this method to specify where to find resources. </p>
1191 *
1192 * @param name
1193 * The resource name
1194 *
1195 * @return A <tt>URL</tt> object for reading the resource, or
1196 * <tt>null</tt> if the resource could not be found
1197 *
1198 * @since 1.2
1199 */
1200 protected URL findResource(String name) {
1201 return null;
1202 }
1203
1204 /**
1205 * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
1640 if (pkg != null) {
1641 packages.put(name, pkg);
1642 }
1643 }
1644 return pkg;
1645 }
1646 }
1647
1648 /**
1649 * Returns all of the <tt>Packages</tt> defined by this class loader and
1650 * its ancestors. </p>
1651 *
1652 * @return The array of <tt>Package</tt> objects defined by this
1653 * <tt>ClassLoader</tt>
1654 *
1655 * @since 1.2
1656 */
1657 protected Package[] getPackages() {
1658 Map<String, Package> map;
1659 synchronized (packages) {
1660 map = new HashMap<>(packages);
1661 }
1662 Package[] pkgs;
1663 if (parent != null) {
1664 pkgs = parent.getPackages();
1665 } else {
1666 pkgs = Package.getSystemPackages();
1667 }
1668 if (pkgs != null) {
1669 for (int i = 0; i < pkgs.length; i++) {
1670 String pkgName = pkgs[i].getName();
1671 if (map.get(pkgName) == null) {
1672 map.put(pkgName, pkgs[i]);
1673 }
1674 }
1675 }
1676 return map.values().toArray(new Package[map.size()]);
1677 }
1678
1679
1680 // -- Native library access --
1748 }
1749 /* unload the library. */
1750 ClassLoader.nativeLibraryContext.push(this);
1751 try {
1752 unload();
1753 } finally {
1754 ClassLoader.nativeLibraryContext.pop();
1755 }
1756 }
1757 }
1758 }
1759 // Invoked in the VM to determine the context class in
1760 // JNI_Load/JNI_Unload
1761 static Class getFromClass() {
1762 return ClassLoader.nativeLibraryContext.peek().fromClass;
1763 }
1764 }
1765
1766 // All native library names we've loaded.
1767 private static Vector<String> loadedLibraryNames
1768 = new Vector<>();
1769
1770 // Native libraries belonging to system classes.
1771 private static Vector<NativeLibrary> systemNativeLibraries
1772 = new Vector<>();
1773
1774 // Native libraries associated with the class loader.
1775 private Vector<NativeLibrary> nativeLibraries
1776 = new Vector<>();
1777
1778 // native libraries being loaded/unloaded.
1779 private static Stack<NativeLibrary> nativeLibraryContext
1780 = new Stack<>();
1781
1782 // The paths searched for libraries
1783 private static String usr_paths[];
1784 private static String sys_paths[];
1785
1786 private static String[] initializePath(String propname) {
1787 String ldpath = System.getProperty(propname, "");
1788 String ps = File.pathSeparator;
1789 int ldlen = ldpath.length();
1790 int i, j, n;
1791 // Count the separators in the path
1792 i = ldpath.indexOf(ps);
1793 n = 0;
1794 while (i >= 0) {
1795 n++;
1796 i = ldpath.indexOf(ps, i + 1);
1797 }
1798
1799 // allocate the array of paths - n :'s = n + 1 path elements
1800 String[] paths = new String[n + 1];
2084 classAssertionStatus.put(className, enabled);
2085 }
2086 }
2087
2088 /**
2089 * Sets the default assertion status for this class loader to
2090 * <tt>false</tt> and discards any package defaults or class assertion
2091 * status settings associated with the class loader. This method is
2092 * provided so that class loaders can be made to ignore any command line or
2093 * persistent assertion status settings and "start with a clean slate."
2094 * </p>
2095 *
2096 * @since 1.4
2097 */
2098 public void clearAssertionStatus() {
2099 /*
2100 * Whether or not "Java assertion maps" are initialized, set
2101 * them to empty maps, effectively ignoring any present settings.
2102 */
2103 synchronized (assertionLock) {
2104 classAssertionStatus = new HashMap<>();
2105 packageAssertionStatus = new HashMap<>();
2106 defaultAssertionStatus = false;
2107 }
2108 }
2109
2110 /**
2111 * Returns the assertion status that would be assigned to the specified
2112 * class if it were to be initialized at the time this method is invoked.
2113 * If the named class has had its assertion status set, the most recent
2114 * setting will be returned; otherwise, if any package default assertion
2115 * status pertains to this class, the most recent setting for the most
2116 * specific pertinent package default assertion status is returned;
2117 * otherwise, this class loader's default assertion status is returned.
2118 * </p>
2119 *
2120 * @param className
2121 * The fully qualified class name of the class whose desired
2122 * assertion status is being queried.
2123 *
2124 * @return The desired assertion status of the specified class.
2125 *
2147 return result.booleanValue();
2148 }
2149 while(dotIndex > 0) {
2150 className = className.substring(0, dotIndex);
2151 result = packageAssertionStatus.get(className);
2152 if (result != null)
2153 return result.booleanValue();
2154 dotIndex = className.lastIndexOf(".", dotIndex-1);
2155 }
2156
2157 // Return the classloader default
2158 return defaultAssertionStatus;
2159 }
2160 }
2161
2162 // Set up the assertions with information provided by the VM.
2163 // Note: Should only be called inside a synchronized block
2164 private void initializeJavaAssertionMaps() {
2165 // assert Thread.holdsLock(assertionLock);
2166
2167 classAssertionStatus = new HashMap<>();
2168 packageAssertionStatus = new HashMap<>();
2169 AssertionStatusDirectives directives = retrieveDirectives();
2170
2171 for(int i = 0; i < directives.classes.length; i++)
2172 classAssertionStatus.put(directives.classes[i],
2173 directives.classEnabled[i]);
2174
2175 for(int i = 0; i < directives.packages.length; i++)
2176 packageAssertionStatus.put(directives.packages[i],
2177 directives.packageEnabled[i]);
2178
2179 defaultAssertionStatus = directives.deflt;
2180 }
2181
2182 // Retrieves the assertion directives from the VM.
2183 private static native AssertionStatusDirectives retrieveDirectives();
2184 }
2185
2186
2187 class SystemClassLoaderAction
2188 implements PrivilegedExceptionAction<ClassLoader> {
|