src/share/classes/java/lang/ClassLoader.java

Print this page
rev 3186 : 6880112: Project Coin: Port JDK core library code to use diamond operator


 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> {