Java class loader-system Class Loader

Source: Internet
Author: User

Java class loader-system Class Loader
System class loaders may be familiar with the system class loaders, but for the sake of completeness, let's talk about the system class loaders first. Public class Test {public static void main (String [] args) {ClassLoader cl1 = Test. class. getClassLoader (). getParent (). getParent (); System. out. println (cl1); ClassLoader cl2 = Test. class. getClassLoader (). getParent (); System. out. println (cl2); ClassLoader l3 = Test. class. getClassLoader (); System. out. println (L3) ;}the printed result is: null sun. misc. launcher $ ExtClassLoader @ dc6a77 sun. misc. launcher $ AppClassLoade R @ 1016632 in fact, this is the three class loaders used in the jdk system. null is the bootstrap classloader. Because it is implemented in c ++, null is printed here. ExtClassLoader is the Extension ClassLoader. AppClassLoader is the App ClassLoader or system classloader. They are responsible for loading classes at their specified locations: 1) Bootstrap ClassLoader is responsible for loading jre/lib/rt in $ JAVA_HOME. all the classes in jar are implemented by C ++, not the ClassLoader subclass. 2) Extension ClassLoader is responsible for loading some jar packages of the extended functions in java platform, including jre/lib/* in $ JAVA_HOME /*. jar or-Djava. ext. jar package in the directory specified by dirs 3) App ClassLoader is responsible for loading the jar package specified in classpath and the relationship between the three class loaders in the directory can be seen through code: the parent of the App ClassLoader is the Extension ClassLoader, and the parent of the Extension ClassLoader is the Bootstrap ClassLoader. The so-called delegation mechanism of the delegation mechanism is that when a class is loaded, the App ClassLoader entrusts its parent (Extension ClassLoader) to load, and the Extension ClassLoader entrusts its parent to load until the Bootstrap ClassLoader, if the parent is not loaded successfully, it is loaded by itself. The above three class loaders except Bootstrap ClassLoader are indirectly inherited from the ClassLoader class (an abstract class cannot be instantiated, but there is no abstract method ), the implementation of the delegate mechanism is implemented by the loadClass method as the template method. The following uses the loadClass source code to analyze the delegation mechanism: Custom class loaders sometimes need to customize our class loaders to meet our special needs. In addition, we generally do not need to destroy the delegate mechanism (an example of a classloader that destroys the delegate mechanism will be introduced later). there are usually two ways to implement this: Inherit the URLClassLoader, for example, public class TestClassLoader extends URLClassLoader {public TestClassLoader (URL [] urls) {super (urls);} public TestClassLoader (URL [] urls, ClassLoader parent) {super (urls, parent) ;}} you only need to call the parent class constructor. You do not need to override other methods. This is also the simplest implementation. You only need to call loadClass for use. The disadvantage is that you can only use the URL to locate the class you want to load. 2. inherit the ClassLoader class and override the findClass method. For example, public class TestClassLoader extends ClassLoader {private String basedir; public TestClassLoader (String basedir, ClassLoader parent) {super (parent); this. basedir = basedir ;}@ Override protected Class <?> FindClass (String name) throws ClassNotFoundException {Class <?> Cls = null; StringBuffer sb = new StringBuffer (basedir); String classname = name. replace ('. ', File. separatorChar) + ". class "; sb. append (File. separator + classname); File classF = new File (sb. toString (); if (! ClassF. exists () {throw new ClassNotFoundException ();} byte [] raw = new byte [(int) classF. length ()]; try {InputStream fin = new FileInputStream (classF); fin. read (raw); fin. close ();} catch (Exception e) {e. printStackTrace ();} cls = defineClass (name, raw, 0, raw. length); return cls ;}} in the findClass method, we can use any method to find the class we want to load. Here we use the method of reading files. The loadClass method is also called during use. The thread context loader is introduced from JDK 1.2. The Methods getContextClassLoader () and setContextClassLoader (ClassLoader cl) in the java. lang. Thread class are used to obtain and set the context class loader of the Thread. If the settings are not performed using the setContextClassLoader (ClassLoader cl) method, the thread inherits the context class loader of its parent thread. The context class loader of the initial thread of the Java application is the system class loader. The code running in the thread can use this class loader to load classes and resources. The delegation mechanism of the Class Loader mentioned above does not solve all the problems encountered in Java application development. Java provides many Service Provider Interfaces (SPI), allowing third parties to implement these interfaces. Common SPI include JDBC, JCE, JNDI, JAXP, and JBI. These SPI interfaces are provided by the Java core library. For example, JAXP's SPI interface definition is included in the javax. xml. parsers package. These SPI implementation codes are probably included as jar packages that Java applications depend on. They can be found through CLASSPATH, for example, implement the jar package contained in Apache Xerces of jaxp spi. The code in the SPI interface often needs to load specific implementation classes. For example, the newInstance () method in the javax. xml. parsers. DocumentBuilderFactory class in JAXP is used to generate a new DocumentBuilderFactory instance. The real classes of the instance here inherit from javax. xml. parsers. DocumentBuilderFactory, which is provided by the SPI implementation. For example, in Apache Xerces, the implemented class is org. apache. xerces. jaxp. DocumentBuilderFactoryImpl. The problem is that the SPI interface is part of the Java core library and loaded by the boot Class Loader. the Java class implemented by SPI is generally loaded by the system class loader. The bootstrap loader cannot find the SPI implementation class because it only loads the Java core library. It cannot be used as a proxy to the system class loader because it is the ancestor class loader of the system class loader. That is to say, the delegation mechanism of the Class Loader cannot solve this problem. The thread context loader solves this problem. If no settings are made, the context class loader of the Java application thread is the system context class loader by default. You can use the thread context class loader in the SPI interface code to successfully load the class to the SPI implementation. The thread context loader is used in many SPI implementations.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.