Java class Loader

Source: Internet
Author: User
Tags apache tomcat

I. Class loader basic concepts 1. Get the class binary bytecode file 2. Convert to Class object (DefineClass () method) 3. Instantiate object two with newinstance (). The tree-like structure of the ClassLoader

The ClassLoader in Java can be broadly divided into two categories, one for the system, the other for Java application developers.
1. Boot class loader (bootstrap class loader): It is used to load Java's core library, which is implemented by C + + and does not inherit from Java.lang.ClassLoader.
2. Extension class loader (Extensions class loader): It is used to load the Java extension library. The implementation of the Java virtual machine provides an extension library directory. The ClassLoader finds and loads the Java class in this directory.
3. System class Loader: It loads Java classes according to the Classpath (CLASSPATH) of the Java application.
Get it by Classloader.getsystemclassloader (). --appclassloader

 Public class Classloadertree {        publicstaticvoid  main (string[] args) {        = Classloadertree. class . getClassLoader ();          while (myloader!=null) {            System.out.println (myloader.tostring ());             = myloader.getparent ();}}    }

/*    [email protected]   * /

Three. Agent mode for Class loader

1. How the Java virtual machine determines that two Java classes are the same: class definition Loader + class Full Name = Class
2. The same class is not generated by the same bytecode file loaded by the different ClassLoader
3. The proxy mode is designed to ensure the type safety of the Java Core library. All Java applications need at least a reference to the Java.lang.Object class, which means that the Java.lang.Object class needs to be loaded into the Java Virtual machine at runtime. If this loading process is done by the Java application's own classloader, it is likely that there are multiple versions of the Java.lang.Object class, and that these classes are incompatible. Through the proxy mode, the loading of the classes of the Java Core Library is accomplished by the bootstrap ClassLoader, which ensures that Java applications are all compatible with the same version of the Java Core Library. Different Class loaders create additional namespaces for classes of the same name. Classes of the same name can and exist in the Java virtual machine, and only need to load them with a different class loader. Classes loaded by different classloader are incompatible, which is equivalent to creating a separate Java class space within the Java virtual machine. This technique is used in many frameworks and is described in more detail later. Four. Procedure for loading a Class 1. The ClassLoader first proxies to the parent class loader to try to load a class. This means that the class loader that actually completes the class loading work and the ClassLoader that started the loading process may not be the same. The completion of class loading is done by calling DefineClass (), and the loading process of the startup class is implemented by calling LoadClass (). The former is called the definition loader for a class (defining loader), which is called the initial loader (initiating loader). When a Java virtual machine determines whether two classes are the same, the class's definition loader is used. That is, it is not important which class loader initiates the loading of the class, it is important to finally define the loader for this class. The correlation between the two kinds of loaders is that the definition loader for a class is the initial loader for the other classes it references. If class Com.example.Outer refers to class Com.example.Inner, the Com.example.Outer class's definition loader is responsible for initiating the loading process of the class Com.example.Inner.
2. Method LoadClass () throws a Java.lang.ClassNotFoundException exception, and the method DefineClass () throws a Java.lang.NoClassDefFoundError exception.
3. After the class loader successfully loads a class, the resulting instance of the Java.lang.Class class is cached. The next time the class is requested to load, the ClassLoader will use the instance of the cached class directly without attempting to load it again. That is, for a class loader instance, a class of the same full name is loaded only once, that is, the LoadClass method is not called repeatedly. Five. Thread context class loader 1. The thread context ClassLoader (contextual class loader) was introduced from the beginning of JDK 1.2. The methods in class Java.lang.Thread Getcontextclassloader () and Setcontextclassloader (ClassLoader cl) are used to get and set the context class loader for the thread. If it is not set by the Setcontextclassloader (ClassLoader cl) method, the thread inherits the context class loader of its parent thread. The context class loader for the initial thread that the Java application runs is the system ClassLoader. Code that runs in a thread can load classes and resources through such loaders.
The class loader's proxy pattern mentioned earlier does not solve all of the classloader problems encountered in Java application development. Java provides a number of service provider interfaces (services Provider INTERFACE,SPI) that allow third parties to provide implementations for these interfaces. The common SPI is JDBC, JCE, JNDI, JAXP, and JBI. These SPI interfaces are provided by the Java Core library, such as the JAXP SPI interface definition contained in the Javax.xml.parsers package. The implementation code for these SPI is likely to be contained in a jar package that is dependent on the Java application, which can be found through the classpath (CLASSPATH), such as the jar packages contained in the Apache xerces that implements the JAXP SPI. The code in the SPI interface often needs to load specific implementation classes. The Newinstance () method in the Javax.xml.parsers.DocumentBuilderFactory class in JAXP is used to generate a new instance of Documentbuilderfactory. The real class of instances here is inherited from Javax.xml.parsers.DocumentBuilderFactory, provided by the implementation of the SPI. As 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 is loaded by the boot class loader, and the Java class implemented by the SPI is typically loaded by the System class loader. The boot ClassLoader is unable to find the SPI implementation class because it only loads the Java core library. It also cannot delegate to the system ClassLoader because it is the ancestor class loader of the system ClassLoader. In other words, the class loader's proxy mode does not solve this problem.
2. The thread context ClassLoader solves this problem. If you do not make any settings, the context class loader for the Java app's thread is the system context class loader by default. Using the thread context class loader in the code of the SPI interface, you can successfully load the class to the SPI implementation. The thread context ClassLoader is used in many implementations of the SPI. Six. Custom Class Loaders
/**ClassLoader: (rewrite Findclass) 1) The LoadClass () method implements the classifier loader's proxy mode 1.finsLoadedClass () to find whether the 2 is loaded. The LOADCLA that called the parent loader was not loaded SS () 3. If unable to load, use Findclass () to find the Class 4. Convert binary bytecode to class instance with DefineClass*/ Public classMydefclassloaderextendsclassloader{PrivateString Rootname;  PublicMydefclassloader (String rootname) { This. Rootname =Rootname; }        protectedClass Findclass (String name)throwsclassnotfoundexception {//rewrite Findclass                byte[] Classfile = This. Getclassfile (name); if(Classfile = =NULL){            Throw Newclassnotfoundexception (); }Else{            returnDefineClass (name, Classfile, 0, classfile.length); }            }    Private byte[] Getclassfile (String PackagePath) {//java.lang.stringInputStream in; Try{ in=NewFileInputStream ( This. Getholepath (PackagePath)); Bytearrayoutputstream OS=NewBytearrayoutputstream (); byte[] Readarray =New byte[1024]; intLength = 0;  while(length = In.read (Readarray))! =-1) {os.write (Readarray,0,length);//bytearrayos output to memory            }            returnOs.tobytearray (); } Catch(Exception e) {}return NULL; }        Privatestring Getholepath (String packagepath) {string path= Packagepath.replace ('. '), File.separatorchar);        SYSTEM.OUT.PRINTLN (path); return  This. rootname+file.separator+path+ ". Class"; }         Public Static voidMain (string[] args)throwsException {System.out.println (Classloader.getsystemclassloader ()); System.out.println (System.getproperty ("Java.class.path"));//D:\homework\homework\myeclipse8\Classloader\bin (Project)System.out.println (NewMydefclassloader ("D:"). Getholepath ("java.lang.String"))); }}
Seven. class loader with Web container 1. The implementation of ClassLoader in WEB applications differs from that of general Java applications. As with Apache Tomcat, each WEB application has a corresponding ClassLoader instance. The ClassLoader also uses proxy mode, and the difference is that it is the first attempt to load a class if it cannot find another proxy to the parent ClassLoader (first on its own). This is contrary to the order of the generic ClassLoader. This is the recommended practice in the Java Servlet specification, which is designed to give the Web application its own class precedence over the classes provided by the Web container (HttpRequest). Eight. Class loader with OSGI1. Osgi™ is a dynamic module system on Java. It provides a service-oriented and component-based runtime environment for developers, and provides a standard way to manage the lifecycle of software. OSGi has been implemented and deployed on many products and has been widely supported in the open source community. Eclipse is built on the basis of OSGi technology.
2. Each module (bundle) in OSGi contains Java packages and classes. A module can declare Java packages and classes (via Import-package) of other modules that it relies on to import (imports), or export its own packages and classes for use by other modules (via Export-package). This means that some Java packages and classes in a module need to be able to be hidden and shared. This is achieved through the class loader mechanism that is specific to OSGi. Each module in OSGi has a corresponding class loader. It is responsible for loading the Java packages and classes that the module contains itself. When it needs to load the class of the Java core library (packages and classes beginning with Java), it will be proxied to the parent classloader (usually the startup ClassLoader) to complete. When it needs to load the imported Java class, it proxies the module to export the Java class to complete the load. Modules can also explicitly declare certain Java packages and classes, which must be loaded by the parent class loader. You only need to set the value of the system property org.osgi.framework.bootdelegation.
3. Suppose there are two modules Bundlea and Bundleb, all of which have their own class loader Classloadera and Classloaderb. The class Com.bundleA.Sample is included in the Bundlea, and the class is declared as exported, which means it can be used by other modules. Bundleb declares the class com.bundleA.Sample provided by the import Bundlea and contains a class com.bundleB.NewSample inherited from Com.bundleA.Sample. When Bundleb starts, its classloader classloaderb need to load class com.bundleB.NewSample, which in turn requires the class Com.bundleA.Sample to be loaded. Since Bundleb declares that the class com.bundleA.Sample is imported, classloaderb the work agent that loads the class com.bundleA.Sample to the Bundlea ClassLoader Classloadera that exports the class. Classloadera finds the class Com.bundleA.Sample inside its module and defines it, the resulting class com.bundleA.Sample instance can be used by all the modules that declare the class to be imported. For classes that begin with Java, they are loaded by the parent ClassLoader. If the system attribute org.osgi.framework.bootdelegation=com.example.core.* is declared, then the class in package Com.example.core is done by the parent ClassLoader.
This class loader structure of the OSGi module allows the different versions of a class to coexist in a Java virtual machine, giving it a lot of flexibility. This difference, however, can be problematic for developers, especially if the module needs to use a third-party-provided library. Here are a few more good suggestions:
1) If a class library is used by only one module, place the jar package of the class library in the module and specify it in the Bundle-classpath.
2) If a class library is shared by multiple modules, you can create a separate module for the class library and declare the Java packages that other modules need to be exported. Other module declarations import these classes.
3) If the class library provides an SPI interface, and the thread context class loader is used to load the Java class implemented by the SPI, the Java class may not be found. If a Noclassdeffounderror exception occurs, first check that the context class loader for the current thread is correct. The ClassLoader can be obtained by Thread.CurrentThread (). Getcontextclassloader (). The ClassLoader should be the class loader corresponding to the module. If not, the class loader corresponding to the module can be obtained first through Class.getclassloader (), and then by Thread.CurrentThread (). Setcontextclassloader () To set the context class loader for the current thread.

Java class Loader

Related Article

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.