Drill down to the JVM class loader

Source: Internet
Author: User
Tags tomcat server java se

01, the class loader principle
02. Class loader tree structure, parent delegate (proxy) mechanism
03. Custom class Loader (file, network, encryption)
04. Thread Context Class loader
05. Server Class Loading principle

1, the role of the class loader
Loads the byte-code content of the class file into memory and converts the static data into a RUN-TIME data structure in the method area, generating a Java.lang.Class object representing the class in the heap as the access gate to the method area class data.

Class Caching
The standard Java SE Class loader can find classes as required, but once a class is loaded into the class loader, it will maintain the load (cache) for a while, but the JVM garbage collector can reclaim these class objects.

2. Class loader hierarchy (tree-like structure)

Boot class loader (Bootstarap class loader) (C)
-it is used to load JAVA core library (content under Java_home/jre/lib/rt.jar or Sun.boot.class.path path), is implemented with native code, does not inherit from Java.lang.ClassLoader.
-Loads the extension class and application class loaders and specifies their parent class loader.

Extended class Loader (Extensions class loader) (Java)
-Used to load JAVA extensions (Java_home/jre/ext/*.jar, or content under the Java.ext.dirs path). The Java Virtual Machine implementation provides an extension library directory in which to find and load Java classes.
-Implemented by Sun.misc.launcher$extclassloader

Application class loader (Application class loader) (Java)
-It is based on Java-applied classpath (CLASSPATH, Java.class.path path Class)
-typically Java-applied classes are loaded by it
-Implemented by Sun.misc.launcher$appclassloader

Custom class Loader (Java-written)
-developers can implement their own classloader by inheriting the Java.lang.ClassLoader class method to meet some special requirements

Java.class.ClassLoader Class Introduction
Role:
The basic responsibility of the-java.lang.classloader class is to find or generate the byte code for the period based on the name of a specified class, and then define a Java class from these byte codes, which is a java.lang.Class instance of the class.
-In addition, ClassLoader is also responsible for loading the required resources for Java applications, such as image files and configuration files.

Related Methods
-GetParent () returns the parent class loader of the class loader
-LoadClass (String name) loads the class named name, and returns the result is an instance of the Java.lang.Class class
-Findclass (String name) looks up a class with the name named, and returns the result as an instance of the Java.lang.Class class
-Findloadedclass (String name) finds a class that has already been loaded with the name named name, and returns the result as an instance of the Java.lang.Class class
-DefineClass (String name,byte[] b,int off,int len) converts the contents of byte array B into a Java class, and the result returned is an instance of the Java.lang.Class class, which is declared final.
-Resolveclass (Class

package com.lyy.test; public class Demo2 {public static void main (string[] args) {System.out.println (Classloader.getsystemclasslo
        Ader ());
        System.out.println (Classloader.getsystemclassloader (). GetParent ()); System.out.println (Classloader.getsystemclassloader (). GetParent (). GetParent ());
        Java_home/jre/lib/rt.jar System.out.println (System.getproperty ("Java.class.path"));
        System.out.println ("=====================================");
        String a = "Gaogao";
        System.out.println (A.getclass (). getClassLoader ());

    System.out.println (a); }
}

Proxy mode for class loader
Agent Mode
-Give the other loader to load the specified class
Parental delegation mechanism
-that is, when a particular class loader receives a request to load a class, first, the load task is delegated to the parent class loader, a retrospective, knowing the highest grandparents, if the parent class loader can complete the class load task, it will return successfully, only if the parent class loader cannot complete this load task.
-The parental delegation mechanism is to ensure the type safety of the Java Core Library.
This mechanism guarantees that no user can define the Java.lang.Object class.
Class Loaders are also the most basic barrier to security, in addition to user-loaded classes.
the mechanism of parental entrustment is a kind of agent mode
-Not all class loaders Adopt a parental delegation mechanism.
The-TOMCAT server class loader also uses proxy mode, but the difference is that it first tries to load a class, and if no more proxies are found to the parent class loader, this is the opposite of the order of the generic ClassLoader.

Custom class Loader
the process of customizing the ClassLoader
-first check whether the requested type has been loaded into the namespace by this class loader,
If already loaded, return directly;
-Delegate class load request to the parent class loader to complete, then return the parent class loader loaded class instance;
-Invokes the findclass of this class loader (...). method, the view gets the corresponding byte code, and if it is fetched, the defineclass (...) is invoked. Import type to method area, return exception loadclass (...) If no byte code is obtained or otherwise fails. LoadClass (...) Throws an exception and terminates the loading process.
-Note: The same class that is loaded by two ClassLoader, the JVM is not considered to be the same class

package com.lyy.temp; public class Hellowrold {public static void main (string[] args) {System.out.println ("AAA");}} 
Package com.lyy.test; /** * Test custom class loader (filesystemclassloader) * @author * */public class Demo3 {public static void main (string[] Arg
        s) throws ClassNotFoundException {Filesystemclassloader load = new Filesystemclassloader ("E:/vip");

        Filesystemclassloader load2 = new Filesystemclassloader ("E:/vip");
        class<?> C = Load.loadclass ("Com.lyy.temp.HelloWrold");
        class<?> C2 = Load.loadclass ("Com.lyy.temp.HelloWrold");

        class<?> C3 = Load2.loadclass ("Com.lyy.temp.HelloWrold");
        class<?> C4 = load2.loadclass ("java.lang.String");

        class<?> c5 = load2.loadclass ("Com.lyy.test.Demo1");
        System.out.println (C.hashcode ());
        System.out.println (C2.hashcode ());
        System.out.println (C3.hashcode ());//The same class, loaded by different loaders, is considered by the JVM to be a distinct class System.out.println (C4.hashcode ());
       System.out.println (C3.getclassloader ());//Custom class loader System.out.println (C4.getclassloader ());//Boot class loader System.out.println (C5.getclassloader ());//system default class loader}}
 

File class loader

Package com.lyy.test;
Import Java.io.ByteArrayOutputStream;
Import Java.io.FileInputStream;
Import java.io.IOException;

Import Java.io.InputStream; /** * Custom File System loader * @author */public class Filesystemclassloader extends classloader{//com.lyy.test.user-

    > D:/myjava/com/lyy/test/user.class private String rootdir;
    Public Filesystemclassloader (String rootdir) {this.rootdir=rootdir; @Override protected class<?> Findclass (String name) throws ClassNotFoundException {Class<?&gt ;

        c = findloadedclass (name);
        First query whether the class has been loaded, if it has already been loaded, return directly to the loaded class, otherwise load the new class if (null!= c) {returns C;
            }else{ClassLoader parent = this.getparent (); c = parent.loadclass (name);
            Delegate to parent class load if (null!= c) {return C;
                }else{byte[] Classdata = getclassdata (name); if (classdata==null) {throw new Classnotfoundexception ();
                }else{C = defineclass (name, classdata,0, classdata.length);
    }} return C;  Private byte[] Getclassdata (string name) {//com.lyy.test.user D:/myjava/com/lyy/test/user.class string

        Path = rootdir+ "/" +name.replace ('. ', '/') + "class";
        Ioutils, you can use it to convert data in a stream into byte data inputstream is = null;
        Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();

            try {is = new FileInputStream (path);
            byte[] buffer = new byte[1024];
            int temp = 0;
            while ((Temp=is.read (buffer))!=-1) {baos.write (buffer,0,temp);
        return Baos.tobytearray ();
            catch (Exception e) {e.printstacktrace ();
        return null;
                }finally{try {if (is!= null) {is.close ();
       } if (BAOs!= null) {             Baos.close ();
            } catch (IOException e) {e.printstacktrace ();

 }
        }
    }
}

Network class loader

Package com.lyy.test;
Import Java.io.ByteArrayOutputStream;
Import Java.io.FileInputStream;
Import java.io.IOException;
Import Java.io.InputStream;

Import Java.net.URL; /** * Network Class LOADER * @author * * */public class Netclassloader extends classloader{//com.lyy.test.user--> www.ba

    idu.com private String Rooturl;
    Public Netclassloader (String rooturl) {this.rooturl=rooturl; @Override protected class<?> Findclass (String name) throws ClassNotFoundException {Class<?&gt ;

        c = findloadedclass (name);
        First query whether the class has been loaded, if it has already been loaded, return directly to the loaded class, otherwise load the new class if (null!= c) {returns C;
            }else{ClassLoader parent = this.getparent (); c = parent.loadclass (name);
            Delegate to parent class load if (null!= c) {return C;
                }else{byte[] Classdata = getclassdata (name);
         if (classdata==null) {throw new ClassNotFoundException ();       }else{C = defineclass (name, classdata,0, classdata.length);
    }} return C;  Private byte[] Getclassdata (string name) {//com.lyy.test.user D:/myjava/com/lyy/test/user.class string

        Path = rooturl+ "/" +name.replace ('. ', '/') + "class";
        Ioutils, you can use it to convert data in a stream into byte data inputstream is = null;
        Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();
            try {URL url = new URL (path);

            is = Url.openstream ();
            byte[] buffer = new byte[1024];
            int temp = 0;
            while ((Temp=is.read (buffer))!=-1) {baos.write (buffer,0,temp);
        return Baos.tobytearray ();
            catch (Exception e) {e.printstacktrace ();
        return null;
                }finally{try {if (is!= null) {is.close (); } if (BAOs!= nulL) {baos.close ();
            } catch (IOException e) {e.printstacktrace ();
 }
        }
    }
}

Cryptographic decryption Loader (reverse operation, des symmetric encryption decryption)

Package com.lyy.test;

/**
 * Test simple encryption Decryption (reverse) Operation
 * @author * */Public
class Demo4 {public

    static void Main (string[) args) throws Exception {
        //test FETCH reverse Operation
//      int a = 3;//0000011
//      System.out.println ( Integer.tobinarystring (A^0xff));

        Encrypted class file, normal ClassLoader failed to load, reported clasformaterror
//      Filesystemclassloader load = new Filesystemclassloader ("E :/vip/temp ");      class<?> C = Load.loadclass ("Hellowrold");      System.out.println (c);

        Decrptclassloader loader = new Decrptclassloader ("E:/vip/temp");
        class<?> C = Loader.loadclass ("Com.lyy.temp.HelloWrold");
        System.out.println (c);
    }
}
Package com.lyy.test;
Import Java.io.ByteArrayOutputStream;
Import Java.io.FileInputStream;
Import java.io.IOException;

Import Java.io.InputStream; /** * Custom File System loader * @author */public class Filesystemclassloader extends classloader{//com.lyy.test.user-

    > D:/myjava/com/lyy/test/user.class private String rootdir;
    Public Filesystemclassloader (String rootdir) {this.rootdir=rootdir; @Override protected class<?> Findclass (String name) throws ClassNotFoundException {Class<?&gt ;

        c = findloadedclass (name);
        First query whether the class has been loaded, if it has already been loaded, return directly to the loaded class, otherwise load the new class if (null!= c) {returns C;
            }else{ClassLoader parent = this.getparent (); c = parent.loadclass (name);
            Delegate to parent class load if (null!= c) {return C;
                }else{byte[] Classdata = getclassdata (name); if (classdata==null) {throw new Classnotfoundexception ();
                }else{C = defineclass (name, classdata,0, classdata.length);
    }} return C;  Private byte[] Getclassdata (string name) {//com.lyy.test.user D:/myjava/com/lyy/test/user.class string

        Path = rootdir+ "/" +name.replace ('. ', '/') + "class";
        Ioutils, you can use it to convert data in a stream into byte data inputstream is = null;
        Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();

            try {is = new FileInputStream (path);
            byte[] buffer = new byte[1024];
            int temp = 0;
            while ((Temp=is.read (buffer))!=-1) {baos.write (buffer,0,temp);
        return Baos.tobytearray ();
            catch (Exception e) {e.printstacktrace ();
        return null;
                }finally{try {if (is!= null) {is.close ();
       } if (BAOs!= null) {             Baos.close ();
            } catch (IOException e) {e.printstacktrace ();
 }
        }
    }
}
Package com.lyy.test;
Import Java.io.ByteArrayOutputStream;
Import Java.io.FileInputStream;
Import java.io.IOException;

Import Java.io.InputStream; /** * Load file System encryption class byte code ClassLoader * @author */public class Decrptclassloader extends classloader{//com.lyy.tes

    T.user--> D:/myjava/com/lyy/test/user.class private String RootDir;
    Public Decrptclassloader (String rootdir) {this.rootdir=rootdir; @Override protected class<?> Findclass (String name) throws ClassNotFoundException {Class<?&gt ;

        c = findloadedclass (name);
        First query whether the class has been loaded, if it has already been loaded, return directly to the loaded class, otherwise load the new class if (null!= c) {returns C;
            }else{ClassLoader parent = this.getparent (); c = parent.loadclass (name);
            Delegate to parent class load if (null!= c) {return C;
                }else{byte[] Classdata = getclassdata (name); if (classdata==null) {throw new ClassNotFoundException ();
                }else{C = defineclass (name, classdata,0, classdata.length);
    }} return C;  Private byte[] Getclassdata (string name) {//com.lyy.test.user D:/myjava/com/lyy/test/user.class string

        Path = rootdir+ "/" +name.replace ('. ', '/') + "class";
        Ioutils, you can use it to convert data in a stream into byte data inputstream is = null;
        Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();

            try {is = new FileInputStream (path);
            int temp =-1; while ((Temp=is.read ())!=-1) {baos.write (TEMP^0XFF);//Fetch reverse operation, equivalent to decryption operation} return Bao
        S.tobytearray ();
            catch (Exception e) {e.printstacktrace ();
        return null;
                }finally{try {if (is!= null) {is.close ();
     } if (BAOs!= null) {baos.close ();           } catch (IOException e) {e.printstacktrace ();
 }
        }
    }
}

Thread Context class loader
Parental delegation mechanism and problem with ClassLoader
in general, ensure that other classes associated with the same class are loaded by the class loader of the current class.
For example, class itself found in the ext, then he came out of some of the classes can only use Ext to find (not lower a level), so some of the app can find, but could not find.
JDBC API He has an internship driven department (mysql/sql server), our JDBC API is loaded by boot or ext, but service prover is loaded by ext or app. Then it is possible to not find driver, in the Java domain, in fact, as long as this API-SPI (Service provide Interface, a specific vendor), will encounter this problem. The
Common SPI has JDBC, JCE, JNXP, and Jbi.

Package com.lyy.test;

/**
 * Thread Context class Loader
 * @author * *
 /
 public
class Demo5 {public

    static void Main (string[] args) thr oWS Exception {
        ClassLoader loader = Demo5.class.getClassLoader ();
        SYSTEM.OUT.PRINTLN (loader);

        ClassLoader laoder2 = Thread.CurrentThread (). Getcontextclassloader ();
        System.out.println (laoder2);

        Thread.CurrentThread (). Setcontextclassloader (New Filesystemclassloader ("e:/vip/"));
        System.out.println (Thread.CurrentThread (). Getcontextclassloader ());

        class<demo1> C = (class<demo1>) thread.currentthread (). Getcontextclassloader (). LoadClass (" Com.lyy.test.Demo1 ");
        System.out.println (c);
        System.out.println (C.getclassloader ());

    }


Class loading mechanism for Tomcat server

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.