📄 classloader.java
字号:
* <code>java.system.class.loader</code>, if defined, is taken to be the * name of the class to use as the system class loader, which must have * a public constructor which takes a ClassLoader as a parent. The parent * class loader passed in the constructor is the default system class * loader. * * <p>Note that this is different from the bootstrap classloader that * actually loads all the real "system" classes. * * <p>A security check will be performed for * <code>RuntimePermission("getClassLoader")</code> if the calling class * is not a parent of the system class loader. * * @return the system class loader * @throws SecurityException if the security check fails * @throws IllegalStateException if this is called recursively * @throws Error if <code>java.system.class.loader</code> fails to load * @since 1.2 */ public static ClassLoader getSystemClassLoader() { // Check if we may return the system classloader SecurityManager sm = SecurityManager.current; if (sm != null) { ClassLoader cl = VMStackWalker.getCallingClassLoader(); if (cl != null && cl != StaticData.systemClassLoader) sm.checkPermission(new RuntimePermission("getClassLoader")); } return StaticData.systemClassLoader; } /** * Defines a new package and creates a Package object. The package should * be defined before any class in the package is defined with * <code>defineClass()</code>. The package should not yet be defined * before in this classloader or in one of its parents (which means that * <code>getPackage()</code> should return <code>null</code>). All * parameters except the <code>name</code> of the package may be * <code>null</code>. * * <p>Subclasses should call this method from their <code>findClass()</code> * implementation before calling <code>defineClass()</code> on a Class * in a not yet defined Package (which can be checked by calling * <code>getPackage()</code>). * * @param name the name of the Package * @param specTitle the name of the specification * @param specVendor the name of the specification designer * @param specVersion the version of this specification * @param implTitle the name of the implementation * @param implVendor the vendor that wrote this implementation * @param implVersion the version of this implementation * @param sealed if sealed the origin of the package classes * @return the Package object for the specified package * @throws IllegalArgumentException if the package name is null or it * was already defined by this classloader or one of its parents * @see Package * @since 1.2 */ protected Package definePackage(String name, String specTitle, String specVendor, String specVersion, String implTitle, String implVendor, String implVersion, URL sealed) { if (getPackage(name) != null) throw new IllegalArgumentException("Package " + name + " already defined"); Package p = new Package(name, specTitle, specVendor, specVersion, implTitle, implVendor, implVersion, sealed); synchronized (definedPackages) { definedPackages.put(name, p); } return p; } /** * Returns the Package object for the requested package name. It returns * null when the package is not defined by this classloader or one of its * parents. * * @param name the package name to find * @return the package, if defined * @since 1.2 */ protected Package getPackage(String name) { Package p; if (parent == null) p = VMClassLoader.getPackage(name); else p = parent.getPackage(name); if (p == null) { synchronized (definedPackages) { p = (Package) definedPackages.get(name); } } return p; } /** * Returns all Package objects defined by this classloader and its parents. * * @return an array of all defined packages * @since 1.2 */ protected Package[] getPackages() { // Get all our packages. Package[] packages; synchronized(definedPackages) { packages = new Package[definedPackages.size()]; definedPackages.values().toArray(packages); } // If we have a parent get all packages defined by our parents. Package[] parentPackages; if (parent == null) parentPackages = VMClassLoader.getPackages(); else parentPackages = parent.getPackages(); Package[] allPackages = new Package[parentPackages.length + packages.length]; System.arraycopy(parentPackages, 0, allPackages, 0, parentPackages.length); System.arraycopy(packages, 0, allPackages, parentPackages.length, packages.length); return allPackages; } /** * Called by <code>Runtime.loadLibrary()</code> to get an absolute path * to a (system specific) library that was requested by a class loaded * by this classloader. The default implementation returns * <code>null</code>. It should be implemented by subclasses when they * have a way to find the absolute path to a library. If this method * returns null the library is searched for in the default locations * (the directories listed in the <code>java.library.path</code> system * property). * * @param name the (system specific) name of the requested library * @return the full pathname to the requested library, or null * @see Runtime#loadLibrary(String) * @since 1.2 */ protected String findLibrary(String name) { return null; } /** * Set the default assertion status for classes loaded by this classloader, * used unless overridden by a package or class request. * * @param enabled true to set the default to enabled * @see #setClassAssertionStatus(String, boolean) * @see #setPackageAssertionStatus(String, boolean) * @see #clearAssertionStatus() * @since 1.4 */ public void setDefaultAssertionStatus(boolean enabled) { defaultAssertionStatus = enabled; } /** * Set the default assertion status for packages, used unless overridden * by a class request. This default also covers subpackages, unless they * are also specified. The unnamed package should use null for the name. * * @param name the package (and subpackages) to affect * @param enabled true to set the default to enabled * @see #setDefaultAssertionStatus(boolean) * @see #setClassAssertionStatus(String, boolean) * @see #clearAssertionStatus() * @since 1.4 */ public synchronized void setPackageAssertionStatus(String name, boolean enabled) { if (packageAssertionStatus == null) packageAssertionStatus = new HashMap(StaticData.systemPackageAssertionStatus); packageAssertionStatus.put(name, Boolean.valueOf(enabled)); } /** * Set the default assertion status for a class. This only affects the * status of top-level classes, any other string is harmless. * * @param name the class to affect * @param enabled true to set the default to enabled * @throws NullPointerException if name is null * @see #setDefaultAssertionStatus(boolean) * @see #setPackageAssertionStatus(String, boolean) * @see #clearAssertionStatus() * @since 1.4 */ public synchronized void setClassAssertionStatus(String name, boolean enabled) { if (classAssertionStatus == null) classAssertionStatus = new HashMap(StaticData.systemClassAssertionStatus); // The toString() hack catches null, as required. classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled)); } /** * Resets the default assertion status of this classloader, its packages * and classes, all to false. This allows overriding defaults inherited * from the command line. * * @see #setDefaultAssertionStatus(boolean) * @see #setClassAssertionStatus(String, boolean) * @see #setPackageAssertionStatus(String, boolean) * @since 1.4 */ public synchronized void clearAssertionStatus() { defaultAssertionStatus = false; packageAssertionStatus = new HashMap(); classAssertionStatus = new HashMap(); } /** * Return true if this loader is either the specified class loader * or an ancestor thereof. * @param loader the class loader to check */ final boolean isAncestorOf(ClassLoader loader) { while (loader != null) { if (this == loader) return true; loader = loader.parent; } return false; } private static URL[] getExtClassLoaderUrls() { String classpath = SystemProperties.getProperty("java.ext.dirs", ""); StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator); ArrayList list = new ArrayList(); while (tok.hasMoreTokens()) { try { File f = new File(tok.nextToken()); File[] files = f.listFiles(); if (files != null) for (int i = 0; i < files.length; i++) list.add(files[i].toURL()); } catch(Exception x) { } } URL[] urls = new URL[list.size()]; list.toArray(urls); return urls; } private static void addFileURL(ArrayList list, String file) { try { list.add(new File(file).toURL()); } catch(java.net.MalformedURLException x) { } } private static URL[] getSystemClassLoaderUrls() { String classpath = SystemProperties.getProperty("java.class.path", "."); StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator, true); ArrayList list = new ArrayList(); while (tok.hasMoreTokens()) { String s = tok.nextToken(); if (s.equals(File.pathSeparator)) addFileURL(list, "."); else { addFileURL(list, s); if (tok.hasMoreTokens()) { // Skip the separator. tok.nextToken(); // If the classpath ended with a separator, // append the current directory. if (!tok.hasMoreTokens()) addFileURL(list, "."); } } } URL[] urls = new URL[list.size()]; list.toArray(urls); return urls; } static ClassLoader defaultGetSystemClassLoader() { return createAuxiliarySystemClassLoader( createSystemClassLoader(getSystemClassLoaderUrls(), createExtClassLoader(getExtClassLoaderUrls(), null))); } static ClassLoader createExtClassLoader(URL[] urls, ClassLoader parent) { if (urls.length > 0) return new URLClassLoader(urls, parent); else return parent; } static ClassLoader createSystemClassLoader(URL[] urls, ClassLoader parent) { return new URLClassLoader(urls, parent) { protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { SecurityManager sm = SecurityManager.current; if (sm != null) { int lastDot = name.lastIndexOf('.'); if (lastDot != -1) sm.checkPackageAccess(name.substring(0, lastDot)); } return super.loadClass(name, resolve); } }; } static ClassLoader createAuxiliarySystemClassLoader(ClassLoader parent) { String loader = SystemProperties.getProperty("java.system.class.loader", null); if (loader == null) { return parent; } try { Constructor c = Class.forName(loader, false, parent) .getConstructor(new Class[] { ClassLoader.class }); return (ClassLoader)c.newInstance(new Object[] { parent }); } catch (Exception e) { System.err.println("Requested system classloader " + loader + " failed."); throw (Error) new Error("Requested system classloader " + loader + " failed.") .initCause(e); } } /** * Before doing anything "dangerous" please call this method to make sure * this class loader instance was properly constructed (and not obtained * by exploiting the finalizer attack) * @see #initialized */ private void checkInitialized() { if (! initialized) throw new SecurityException("attempt to use uninitialized class loader"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -