Java classloader-----User-defined class loader implementation

Source: Internet
Author: User

The Java ClassLoader is mainly divided into the following types:

    • The class loader provided by the JVM
      1. Root ClassLoader: The underlying implementation that primarily loads the Java Core Class library (for example: java.lang.*)
      2. Extension ClassLoader: Using Java code implementation, mainly loaded as: jre/lib/ext/under the Extension class library. ( the parent class loader is the root ClassLoader )
      3. System ClassLoader (Application class loader): Use Java code implementation to load classes under the Classpath directory. ( the parent class loader is the extension classloader )
    • User-defined class loader: to inherit the ClassLoader class to implement a custom ClassLoader.

The ClassLoader is responsible for loading the Java bytecode file into the virtual machine memory, which is the life cycle of the class's loading process. (This is the life cycle of the Class)

Here is the implementation process and code for the user-defined class loader:

Implementing a user-defined class loader needs to inherit the ClassLoader class and override the Findclass method, as shown in the code below

 PackageCom.space;ImportJava.io.ByteArrayOutputStream;ImportJava.io.File;ImportJava.io.FileInputStream;Importjava.io.FileNotFoundException;Importjava.io.IOException;ImportJava.io.InputStream; Public classMyclassloaderextendsClassLoader {PrivateString path= "/home/luciel/";//Default Load Path        PrivateString name;//class loader name        Private FinalString filetype= ". Class";//File Type             PublicMyclassloader (String name) {//TODO auto-generated Constructor stub        Super();  This. name=name; }         PublicMyclassloader (ClassLoader parent,string name) {Super(parent);  This. name=name; } @Override PublicClass<?> Findclass (String name)throwsClassNotFoundException {//TODO auto-generated Method Stub        byte[] b=loadclassdata (name); returnDefineClass (name, B, 0, b.length); }        Private byte[] loadClassData (String name) {byte[] Data=NULL; InputStream in=NULL; Name=name.replace ('. ', '/')); Bytearrayoutputstream out=NewBytearrayoutputstream (); Try{ in=NewFileInputStream (NewFile (path+name+filetype)); intLen=0;  while( -1!= (len=In.read ()))            {out.write (len); } Data=Out.tobytearray (); } Catch(FileNotFoundException e) {//TODO auto-generated Catch blockE.printstacktrace (); } Catch(IOException e) {//TODO auto-generated Catch blockE.printstacktrace (); }finally{            Try{in.close ();            Out.close (); } Catch(IOException e) {//TODO auto-generated Catch blockE.printstacktrace (); }        }        returndata; }         PublicString GetPath () {returnpath; }     Public voidSetPath (String path) { This. Path =path; } @Override PublicString toString () {//TODO auto-generated Method Stub        return  This. Name; }}
 Public Myclassloader (String name) {        //  TODO auto-generated constructor stub        Super ();         this. name=name;}

This constructor method calls the ClassLoader non-parametric construction method from the ClassLoader source code can be drawn: Call this construction method will let the system ClassLoader become the class loader's parent loader. (Note: The parent ClassLoader here is not necessarily an inheritance relationship, but a wrapper relationship).

Example of implementing a network ClassLoader in the Java API when overriding the Findclass method, the API example is as follows:

classNetworkclassloaderextendsClassLoader {String host; intPort;  PublicClass Findclass (String name) {byte[] B =loadclassdata (name); returnDefineClass (name, B, 0, b.length); }         Private byte[] loadClassData (String name) {//load the class data from the connection              . . .         } }

Here is the test code for the test class and the Main method class:

1  PackageCom.space;2 3  Public classColor {4      PublicColor () {5         //TODO auto-generated Constructor stub6System.out.println ("Color is loaded by" + This. GetClass (). getClassLoader ());7         8     }9}
1  PackageCom.space;2 3  Public classRedextendscolor{4     5      PublicRed () {6         //TODO auto-generated Constructor stub7System.out.println ("Red is loaded by" + This. GetClass (). getClassLoader ());8         9     }Ten  One}
1  PackageCom.space;2 3  Public classTestmyclassloader {4     5      Public Static voidMain (string[] args)throwsException {6         7Myclassloader loader1=NewMyclassloader ("Loader1");8         9Loader1.setpath ("/home/luciel/test1/");Ten          OneMyclassloader loader2=NewMyclassloader (Loader1, "Loader2"); A          -Loader2.setpath ("/home/luciel/test2/"); -          theMyclassloader loader3=NewMyclassloader (NULL, "Loader3"); -          -Loader3.setpath ("/home/luciel/test3/"); -          +Loadclassbymyclassloader ("Com.space.Red", loader2); -          +Loadclassbymyclassloader ("Com.space.Red", Loader3); A     } at      -     Private Static voidLoadclassbymyclassloader (String name,classloader loader)throwsexception{ -          -Class<?> c=Loader.loadclass (name); -Object obj=c.newinstance (); -     } in  -}

Create the appropriate environment according to the path passed to the three ClassLoader in the main method and copy the class class of com.space.Red, Com.space.Color to

/home/luciel/test1/and/home/luciel/test2/and/home/luciel/test3/ Directories to copy Com.space.TestMyClassLoader and Com.space.MyClassLoader
/home/luciel/main/and execute in this directory

The results of the final run are shown below:

[Email protected] main]# java Com.space.TestMyClassLoaderColor is loaded by loader1red are loaded by Loader1color D by loader3red are loaded by Loader3
Loadclassbymyclassloader ("com.space.Red", Loader2);
As in the test code we call Loader2 to load the red class but the red class prints out the load by Loader1, because the ClassLoader adheres to the parent-delegate mechanism Loader2 wraps Loader1 as its parent loader when it is created. When Loader1 is created, the parent loader is the System class loader because it calls a constructor that does not pass in the parent ClassLoader. So the relationship of several loaders is as follows:

Because the loader1 path has a red class class file so loader1 can load, so the class loader printed in the Red class construction method is Loader1.

My door seems to only load the red class but the result is that the color parent class is loaded, and the color class is loaded before the red class because the Red class actively uses the color class, so before initializing the red class, you must first initialize the color class. To initialize it must be loaded first, so the output information of the color class is printed first. (about the active use of the class if you are not clear can check, a total of 6 kinds)

Loadclassbymyclassloader ("com.space.Red", Loader3);
Then analyze the second Test code, because the Loader3 is created when the parent class loader is null, see the following about the ClassLoader class source code or view the Java API
/*** Returns the parent class loader for delegation. Some implementations * Use <tt>null</tt> to represent the bootstrap class loader.  This method * would return <tt>null</tt> in such implementations if this class loader ' s * Parent is the     Bootstrap class loader. * * <p> If A security manager is present, and the Invoker ' s class loader are * not <tt>null</tt> Ancestor of this class loader, then this * method invokes the Security manager ' s {@link* Securitymanager#checkpermission (java.security.Permission) * <TT>CHECKPERMISSION</TT>} method wi Th a {@link* Runtimepermission#runtimepermission (String) * <tt>runtimepermission ("getClassLoader") </tt>} per  Mission to verify * access to the parent class loader is permitted.  If not, A * <tt>SecurityException</tt> 'll be thrown. </p> * *@returnThe parent <tt>ClassLoader</tt> * *@throwsSecurityException * If A security manager exists and its <tt>checkPermission</tt> *     Method doesn ' t allow access to this class loader ' s parent class * Loader. *     * @since1.2*/@CallerSensitive Public FinalClassLoader getParent () {if(Parent = =NULL)            return NULL; SecurityManager SM=System.getsecuritymanager (); if(SM! =NULL) {checkclassloaderpermission (parent, Reflection.getcallerclass ()); }        returnparent; }
The GetParent method describes the following text:
* Returns the parent class loader for delegation. Some implementations * Use <tt>null</tt> to represent the bootstrap class loader. This method * would return <tt>null</tt> in such implementations if this class loader ' s * parent is the Bootstrap class loader.
Meaning that we can use NULL to represent the Bootstrap class loader (root loader)
So Loader3 's parent ClassLoader is , and the root ClassLoader only loads those system core class libraries, and obviously our red and color classes do not fall into this range, and we can only let loader3 load, The Loader3 load path has a byte code corresponding to these two classes can be loaded successfully, so the class loader of red and color class is Loader3


The above is a summary of my recent knowledge of the ClassLoader when learning about the JVM.

Java classloader-----User-defined class loader implementation

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.