AnalysisAppclassloader, extclassloaderRelationship with urlclassloader
Test code:
Class Hello {Public String STR = "Hello World"; Public void fun () {system. out. println (STR) ;}} public class test {public static void main (string [] ARGs) {hello = new Hello (); Hello. fun (); system. out. println ("----------------------"); // classloader classloaderofhello = hello. class. getclassloader (); system. out. println ("Hello is loaded by:" + classloaderofhello); system. out. println ("------------- --------- "); // Class Object of the Hello class loader class appclazz = classloaderofhello. getclass (); // analyzes the class inheritance relationship of the Class Object of the Hello class loader while (appclazz! = NULL) {system. out. println (appclazz); appclazz = appclazz. getsuperclass ();} system. out. println ("----------------------"); // obtain the Class Object classclass extclazz = classloaderofhello of the loader. getparent (). getclass (); While (extclazz! = NULL) {system. Out. println (extclazz); extclazz = extclazz. getsuperclass ();}}}
Conclusion:
1. the user-defined class is loaded by the application (system) Class Loader appclassloader.
2. In the parent delegation mechanism, the extension class loaderExtclassloaderIs the father of appclassloader.
3. Both appclassloader and extclassloader are extended to the urlclassloader loader.
4. It also indicates that appclassloader does not inherit extclassloader.
Inheritance relationship:
Java. Lang. Object
--- Java. Lang. classloader
--- Java. Security. secureclassloader
--- Java.net. urlclassloader
--- Sun. Misc. launcher $ extclassloader
Java. Lang. Object
--- Java. Lang. classloader
--- Java. Security. secureclassloader
--- Java.net. urlclassloader
--- Sun. Misc. launcher $ appclassloader
In fact, it is very simple. You can simply look at the source code of appclassloader. Haha, I finally found a good stuff.
Jdk7: http://download.java.net/openjdk/jdk7/
JDK 6:Http://download.java.net/openjdk/jdk6/
Download the source code.
Now let's look at the source code:
/** * The class loader used for loading from java.class.path. * runs in a restricted security context. */ static class AppClassLoader extends URLClassLoader { static { ClassLoader.registerAsParallelCapable(); } public static ClassLoader getAppClassLoader(final ClassLoader extcl) throws IOException { final String s = System.getProperty("java.class.path"); final File[] path = (s == null) ? new File[0] : getClassPath(s); return AccessController.doPrivileged( new PrivilegedAction<AppClassLoader>() { public AppClassLoader run() { URL[] urls = (s == null) ? new URL[0] : pathToURLs(path); return new AppClassLoader(urls, extcl); } }); } /* * Creates a new AppClassLoader */ AppClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent, factory); } /** * Override loadClass so we can checkPackageAccess. */ public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { int i = name.lastIndexOf('.'); if (i != -1) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPackageAccess(name.substring(0, i)); } } return (super.loadClass(name, resolve)); } /** * allow any classes loaded from classpath to exit the VM. */ protected PermissionCollection getPermissions(CodeSource codesource) { PermissionCollection perms = super.getPermissions(codesource); perms.add(new RuntimePermission("exitVM")); return perms; } /** * This class loader supports dynamic additions to the class path * at runtime. * * @see java.lang.instrument.Instrumentation#appendToSystemClassPathSearch */ private void appendToClassPathForInstrumentation(String path) { assert(Thread.holdsLock(this)); // addURL is a no-op if path already contains the URL super.addURL( getFileURL(new File(path)) ); } /** * create a context that can read any directories (recursively) * mentioned in the class path. In the case of a jar, it has to * be the directory containing the jar, not just the jar, as jar * files might refer to other jar files. */ private static AccessControlContext getContext(File[] cp) throws java.net.MalformedURLException { PathPermissions perms = new PathPermissions(cp); ProtectionDomain domain = new ProtectionDomain(new CodeSource(perms.getCodeBase(), (java.security.cert.Certificate[]) null), perms); AccessControlContext acc = new AccessControlContext(new ProtectionDomain[] { domain }); return acc; } }
Ha, after reading the source code of appclassloader, you can understand that appclassloader inherits urlclassloader and the constructor calls the structure of urlclassloader directly.
The loadclass (string name, Boolean resolve) method is just a simple package security check, and then the loadclass (string name, Boolean resolve) method of classloader is called. Otherwise, it's similar .. so its function is similar to urlclassloader...
The extclassloader is similar. You can see the source code:
/* * Creates a new ExtClassLoader for the specified directories. */ public ExtClassLoader(File[] dirs) throws IOException { super(getExtURLs(dirs), null, factory); } private static File[] getExtDirs() { String s = System.getProperty("java.ext.dirs"); File[] dirs; if (s != null) { StringTokenizer st = new StringTokenizer(s, File.pathSeparator); int count = st.countTokens(); dirs = new File[count]; for (int i = 0; i < count; i++) { dirs[i] = new File(st.nextToken()); } } else { dirs = new File[0]; } return dirs; } private static URL[] getExtURLs(File[] dirs) throws IOException { Vector<URL> urls = new Vector<URL>(); for (int i = 0; i < dirs.length; i++) { String[] files = dirs[i].list(); if (files != null) { for (int j = 0; j < files.length; j++) { if (!files[j].equals("meta-index")) { File f = new File(dirs[i], files[j]); urls.add(getFileURL(f)); } } } } URL[] ua = new URL[urls.size()]; urls.copyInto(ua); return ua; } /* * Searches the installed extension directories for the specified * library name. For each extension directory, we first look for * the native library in the subdirectory whose name is the value * of the system property <code>os.arch</code>. Failing that, we * look in the extension directory itself. */ public String findLibrary(String name) { name = System.mapLibraryName(name); URL[] urls = super.getURLs(); File prevDir = null; for (int i = 0; i < urls.length; i++) { // Get the ext directory from the URL File dir = new File(urls[i].getPath()).getParentFile(); if (dir != null && !dir.equals(prevDir)) { // Look in architecture-specific subdirectory first // Read from the saved system properties to avoid deadlock String arch = VM.getSavedProperty("os.arch"); if (arch != null) { File file = new File(new File(dir, arch), name); if (file.exists()) { return file.getAbsolutePath(); } } // Then check the extension directory File file = new File(dir, name); if (file.exists()) { return file.getAbsolutePath(); } } prevDir = dir; } return null; } private static AccessControlContext getContext(File[] dirs) throws IOException { PathPermissions perms = new PathPermissions(dirs); ProtectionDomain domain = new ProtectionDomain( new CodeSource(perms.getCodeBase(), (java.security.cert.Certificate[]) null), perms); AccessControlContext acc = new AccessControlContext(new ProtectionDomain[] { domain }); return acc; } }