Java class Loader

Source: Internet
Author: User

Class Loader Description

The class loader is responsible for loading the. class file into memory and generating a Java.lang.Class instance for the class.

Once a class is loaded into the JVM, the same class is not added again. The unique identity of a class in the JVM is: the class name, the package name where the class resides, and the class loader.

When the JVM starts, it forms an initial class loader hierarchy consisting of three classloader:

    • BootStrap ClassLoader: root class loader;
    • Extension ClassLoader: extension class loader;
    • System ClassLoader: Class loader.

The root ClassLoader, which is responsible for loading the Java core Class (that is, the jar package under Java_home/jre/lib). When you use the-xbootclasspath option or specify Sun.boot.class.path System properties by using the-D option, you can also specify to load additional classes. The root ClassLoader is special, and he is not a subclass of Java.lang.ClassLoader, but is implemented by the JVM itself.

The extension ClassLoader, which is responsible for loading the jar packages under the JRE's extended directory (that is, the Java_home/jre/lib/ext directory).

The system ClassLoader, which is responsible for loading the-classpath option from command Java or Java.class.path System Properties, or the jar package and classpath specified by the CLASSPATH environment variable, or the current classpath, when the JVM starts. The program can get the System class loader by ClassLoader static method Getsystemclassloader () method.

In addition to the three kinds of loaders provided by Java, developers can implement their own classloader, and the custom ClassLoader is implemented by inheriting ClassLoader.

The hierarchy of these four kinds of loaders in the JVM

: The root ClassLoader is the parent classloader of the Extension class loader, and the extension ClassLoader is the parent classloader of the system ClassLoader, and if not specifically specified, the user-defined ClassLoader is used as the parent loader for the system ClassLoader.

It is necessary to mention that the parent-child relationship between ClassLoader is not a parent-child relationship on class inheritance, but rather a relationship between class loader instances.

Class loading mechanism

The class loading mechanism of the JVM consists of the following three mechanisms:

    • Overall responsibility: The overall responsibility mechanism is that when a class loader is responsible for loading a class, other classes that the class relies on and references will also be loaded by the ClassLoader, unless explicitly loaded with another classloader;
    • Parent class Delegate: The parent class delegate mechanism is to say that when a class loader is responsible for loading a class, let the parent ClassLoader try to load the class and attempt to load it from its own classpath if it fails to load.
    • Caching mechanism: The caching mechanism guarantees that all classes that have been loaded will be cached. When a class loader is responsible for loading a class, the class is first searched from the cache, and the class is loaded and stored in the cache only if the class object does not exist in the cache. This is why we have modified a class to restart the JVM and the adjustment will take effect.

The class loader load class takes approximately 8 steps:

    1. Detects if the target class has been loaded (that is, if there is a class in the cache), and if so, enters the eighth step directly;
    2. If the parent loader does not exist (there are two scenarios where the parent loader does not exist, either the current loader's parent is the root loader, or the current loader is the root loader), then the fourth step is skipped, and if the parent loader exists, the third step is performed;
    3. Requests the parent loader to load the target class, and if it succeeds to the eighth step, skips to step fifth if unsuccessful;
    4. The request uses the root loader to load the target class, and if it succeeds to step eighth, it jumps to step seventh if unsuccessful;
    5. Look for the. class file (looked up from the loading path of the associated ClassLoader), and if found, executes part sixth and does seventh if it is not found;
    6. Load the class from the file, and jump to the eighth step if the load is successful;
    7. Throw classnotfoundexception;
    8. Returns the class.
Custom Class Loaders

The class loader in the JVM except for the root ClassLoader is an instance of the ClassLoader subclass. Developers can implement a custom class loader by inheriting ClassLoader and overriding ClassLoader methods.

The ClassLoader class has three key methods:

    • LoadClass (String name, Boolean resolve): This method is the entry point for ClassLoader, which loads the class according to the specified binary name;
    • Findclass (String name): Finds a class based on the specified binary name;
    • DefineClass (String name, byte[] B, int off, int len): reads the bytecode file of the specified class (that is, the. class file) into the byte array byte[] B, and converts it into a class object. The bytecode file can originate from a network or a disk.

To implement a custom ClassLoader, you can do so by overriding LoadClass or Findclass. However, it is generally recommended to rewrite Findclass instead of LoadClass, and take a look at the LoadClass steps:

    • Use Findloadclass to check if the class has been loaded and return directly if it is already loaded;
    • Call the LoadClass method on the parent class loader. If the parent class loader is null, the root classloader is used to load the device;
    • Call the Findclass method to find the class.

From above, the overriding Findclass method avoids overriding the default class loader's parent class delegate and caching mechanisms.

The following is an example of a custom class loader:

 Packagecom.zhyea.test;ImportJava.io.File;ImportJava.io.FileInputStream;Importjava.io.IOException;ImportJava.io.InputStream;ImportJava.lang.reflect.Method;/*** Custom Class Loader instance *@authorRobin **/ Public classMyclassloaderextendsClassLoader {/*** Read class file * *@paramFilePath * class file path *@return     * @throwsIOException*/    Private byte[] GetBytes (String filePath)throwsIOException {InputStream in=NULL; Try{File File=NewFile (FilePath); LongLength =file.length (); Inch=Newfileinputstream (file); byte[] buffer =New byte[(int) length]; intHasread =in.read (buffer); if(Hasread! =length) {                Throw NewIOException ("Unable to read all files:" + Hasread + "! =" +length); }            returnbuffer; } finally {            if(NULL!=In ) In.close (); }    }    /*** Compiling java files * *@paramJavafile * java files *@return     * @throwsIOException *@throwsinterruptedexception*/    Private BooleanCompile (String javafile)throwsIOException, interruptedexception {//Call the System javac commandProcess p = runtime.getruntime (). EXEC ("Javac" +javafile); //Force other threads to wait for this thread to finishp.waitfor (); //gets the exit value of the JAVAC thread        intRTN =P.exitvalue (); //returns whether the compilation was successful        returnRTN = = 0; }            /*** Rewrite ClassLoader's Findclass class*/@OverrideprotectedClass<?> Findclass (String name)throwsclassnotfoundexception{Class<?> Clazz =NULL; String Javapath= Name.replace (".", "/"); String Javafilename= Javapath + ". Java"; String Classfilename= Javapath = ". Class"; File Javafile=NewFile (javafilename); File Classfile=NewFile (classfilename); if(Javafile.exists () && (!classfile.exists () | | javafile.lastmodified () >classfile.lastmodified ())) {            Try{                if(!compile (javafilename) | |!classfile.exists ()) {                    Throw NewClassNotFoundException ("Class not Found:" +javafilename); }            }Catch(Exception e) {e.printstacktrace (); }        }                if(Classfile.exists ()) {Try{                byte[] Raw =getBytes (classfilename); Clazz= defineclass (name, raw, 0, raw.length); }Catch(Exception e) {e.printstacktrace (); }        }                if(NULL==clazz) {            Throw Newclassnotfoundexception (name); }                returnClazz; }         Public Static voidMain (string[] args)throwsexception{String javaname= "Com.zhyea.test.MyTest"; Myclassloader MCL=NewMyclassloader (); Class<?> Clazz =Mcl.loadclass (javaname); Method Main= Clazz.getmethod ("Main", (NewString[0]). GetClass ()); Object[] Arrs={args}; Main.invoke (NULL, Arrs); }    }

It is easy to attach the test class for the demo:

 Package com.zhyea.test; /**  @author*/Publicclass  MyTest    {public  staticvoid  main (string[] args) {        System.out.println ("This is a test!" );    }}

Using a custom class loader, you can do the following:

    • Automatic verification of digital signatures before executing code;
    • The code is decrypted according to the user-supplied password, thus the code obfuscation can be implemented to avoid decompile the class file;
    • Dynamically load classes according to user requirements;
    • The other data is loaded into the application in bytecode form according to the application requirements.
URLClassLoader class

URLClassLoader is the parent class of the Extension class loader class and the System class loader class. The URLClassLoader feature is powerful, you can get Java files locally to load classes, or you can get remote files to load classes.

Demo under:

 Packagecom.zhyea.test;ImportJava.net.URL;ImportJava.net.URLClassLoader; Public classUcltest { Public Static voidMain (string[] args)throwsException {url[] URLs= {NewURL ("File:com.zhyea.test.MyTest.java")}; URLClassLoader UCL=NewURLClassLoader (URLs); MyTest MT= (MyTest) ucl.loadclass ("Com.zhyea.test.MyTest"). newinstance ();        Mt.test ();    Ucl.close (); }} Packagecom.zhyea.test;/*** URLClassLoader Test class for demo *@authorRobin **/ Public classMyTest { Public voidTest () {System.out.println ("This is a Test 2!"); }}

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.