Java class Loader

Source: Internet
Author: User

Java class loader (class loader) is a very important concept, has always wanted to write a blog about this, today read a lot of other people's blog, also to write, hope to write understand.

First understand the concept of class loader:

As the name implies, the ClassLoader (class loader) is used to load Java classes into a Java virtual machine. In general, Java virtual machines use Java classes in the following way: Java source programs (. java files) are converted to Java bytecode (. class files) after being compiled by the Java compiler. The ClassLoader is responsible for reading the Java byte code and converting it into java.lang.Class an instance of the class. Each such instance is used to represent a Java class. newInstance()an object of the class can be created by means of this instance. The actual situation can be more complex, such as the Java byte code may be generated dynamically through the tool, or it may be downloaded over the network. For example: when we

There is a Class A, first Javac. A.java, generated the A.class file, this time, then Java A, at this time the JVM needs to load Class A, it has to the class loader to, when the class loader is useful when it comes to a class load to the JVM, specifically how to load the following introduction.

Understand the basic concept of the classloader, we would like in Java everything is an object, the ClassLoader is a Java class, then who will load it? --->JVM

When the JVM starts, it starts the ClassLoader in Jre/rt.jar: Bootstrap ClassLoader, which loads the Java core API, and then launches the extension ClassLoader extclassloader loading the extension class. and load the user program loader appclassloader, and specify Extclassloader as his parent class;

The ClassLoader in Java can be broadly divided into two categories, one for the system, the other for Java application developers. There are three main types of ClassLoader available in the system:

    • Boot class loader (bootstrap class loader): It is used to load Java's core library, is implemented in C + +, does not inherit from java.lang.ClassLoader .
    • 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.
    • System class Loader: It loads Java classes according to the Classpath (CLASSPATH) of the Java application. In general, Java-applied classes are loaded by it. You can ClassLoader.getSystemClassLoader() get it by.

The parent class loader of the system ClassLoader is the extension class loader, and the extension ClassLoader's parent ClassLoader is the bootstrap ClassLoader, and in Java the parental delegate mode,--> loads a class, first bootstrap is searched, and extension is not found. ClassLoader Search, the end is the app ClassLoader, so that can effectively avoid security problems.

Basic concepts here, let's take a look at the Java.lang.ClassLoader class: ClassLoader is an abstract class, which is known to be loaded by bootstrap ClassLoader, and all class loader implementation classes ( In addition to Bootstrap ClassLoader), you need to inherit the class,

getParent () Returns the class loader's parent class loader.
loadclass (String name) If the class's parent class loader is bootstrap ClassLoader is named   the name class that returns the result of   Java.lang.Class class instance.
findclass (String name) Find the class with name   name , and return the result is   Java.lang.Class an instance of the class.
findloadedclass (String name) Find the already loaded class with name   name , returning the result is a   an instance of the Java.lang.Class class.
defineclass (String name, byte[] B, int off, int len)   byte array; b is converted to a Java class, and the result is   an instance of the Java.lang.Class class. This method is declared as   final .
resolveclass (class<?> c) link to the specified Java class.
    1. First, check if the class has already been loaded
    2. The JVM specification specifies that ClassLoader can retain the class it loads in the cache, and if a class has already been loaded, it is fetched directly from the cache

Protected synchronized class<?> loadclass (String name, Boolean resolve)
Throws ClassNotFoundException
{
First, check if the class has already been loaded
Class C = findloadedclass (name);
if (c = = null) {
try {
if (parent! = NULL) {
c = Parent.loadclass (name, false);
} else {
c = FINDBOOTSTRAPCLASS0 (name);
}
} catch (ClassNotFoundException e) {
If still not found, then invoke Findclass in order
To find the class.
c = findclass (name);
}
}
if (resolve) {
Resolveclass (c);
}
return C;
}

Call the FindBootstrapClass0 () method if it has not been loaded, official text:

    1. Invoke to findLoadedClass(String) Check if the class has already been loaded.

    2. Invoke the loadClass method on the parent class loader. If the parent is null for the class loader built-in to the Vsan is used, instead.

    3. Invoke the findClass(String) method to find the class.

As can be seen from the above: Class loader loading a class, first through the class name to determine whether the class has been loaded, if it is loaded, go directly to the cache, if not loaded, then use the System class loader to load it (Systems class loader), not loaded successfully, Call the FindBootstrapClass0 (name) method to load, and if none of the two are successful, call the Findclass (String name) method to find the class again.

Thread Context class Loader:

There are two methods in the thread class: Getcontextclassloader (), Setcontextclassloader (CL), which is used to get and set the context class loader for the thread, if it is not set by means of a 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. (Sun.misc.launcher$appclassloader) code that runs in a thread can load classes and resources through such loaders.

The

Proxy mode of the class loader 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 package contained in the  apache xerces that implements the JAXP SPI. The code in the SPI interface often needs to load specific implementation classes. such as   in JAXP;   in the javax.xml.parsers.DocumentBuilderFactory class; newinstance () method is used to generate an instance of a new documentbuilderfactory . The real class of the instance here is inherited from   javax.xml.parsers.DocumentBuilderFactory , provided by the implementation of the SPI. For example, in Apache Xerces, the implemented class is   Org.apache.xerces.jaxp.DocumentBuilderFactoryImpl . The problem is that the interface of the SPI is part of the Java Core Library, which 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.

The thread context ClassLoader just 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.

In fact, in the Java application All programs are running in the thread, if the program is not manually set ClassLoader, for the general Java class The following two ways to obtain the ClassLoader is usually the same

This.getClass.getClassLoader ();
Thread.CurrentThread (). Getcontextclassloader ();
The ClassLoader obtained by the method is static, indicating who is the loader of the class, and the ClassLoader that the method two obtains is dynamic, who executes (a thread), which is the classloader of the executor. For singleton mode classes, static classes, etc., once loaded, this instance is called by many programs (threads), and for these classes, the ClassLoader of the loaded classloader and execution threads are usually different.

Class.forName

Class.forNameis a static method that can also be used to load classes. There are two forms of the method: Class.forName(String name, boolean initialize, ClassLoader loader) and Class.forName(String className) . The first form of the parameter represents the full name of the class, whether the class is initialized, or the ClassLoader that is name initialize loader used when loading. The second form is equivalent to setting the value of the parameter to initialize true loader the class loader of the current class. Class.forNamea very common usage is when the database driver is loaded. such as Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance() the driver used to load Apache Derby database.

/******** basic concept ends here, then develop your own ClassLoader ******************/

First we need to know why we need to develop our own classloader. For example, your application transmits byte codes for Java classes over the network, and for security purposes, these byte codes are encrypted. At this point you will need your own classloader to read the encrypted byte code from a network address, then decrypt and validate, and finally define the classes to run in the Java virtual machine to

We write our own class loader general rewrite Findclass (name) This method can be

Suppose: We have a HelloWorld class with the following code:

1  Public classHelloWorld2 { 3  PublicHelloWorld () {4System.out.println ("Test"); 5 } 6  Public Static voidMain (string[] args) {7System.out.println ("Hello World"); 8 } 9}

At this point we don't want to load it with the System class loader of Java, but our own classloader to load it, then let our class loader class inherit the Java.lang.ClassLoader class, and we'll implement it ourselves. Loader

Findclass () method, step:

1: Find the class you want to load based on the class name passed in by the constructor method

2: Use the Java.lang.ClassLoader findloadedclass (name) method to determine if there is a cache in the class, if there is a direct return, no, then proceed to the next

3: Because our goal is to convert the class we want to load into a byte[] array, and then define the class with the This.defineclass (name, B, off, Len) method, to the virtual machine so we work in this direction, the code does not explain too much, There are some java.nio.* classes that will specifically write a blog to tell

1  Public classMyclassloaderextendsclassloader{2     3     PrivateString RootDir;4     5      PublicMyclassloader (String rootdir) {6          This. RootDir =RootDir;7     }8     9     Ten @Override One     protectedClass<?> Findclass (String name)throwsClassNotFoundException { AClass<?> Clazz = This. Findloadedclass (name); -         if(Clazz = =NULL){ -             Try { theString Classfile =Nametopath (name); -FileInputStream in =NewFileInputStream (classfile); -                 //writes the target class to +FileChannel channel =In.getchannel (); -                  +Bytearrayoutputstream out =NewBytearrayoutputstream (); AWritablebytechannel Bytechannel =Channels.newchannel (out); at                 //defines a byte buffer that has a human length of 1024 size -Bytebuffer buffer = bytebuffer.allocate (1024); -                  while(true){ -                     intReadnum =channel.read (buffer); -                     if(Readnum = =-1){ -                          Break; to                     } - Buffer.flip (); the bytechannel.write (buffer); * buffer.clear ();Panax Notoginseng                 } -                  the channel.close (); +                 byte[] ByteArray =Out.tobytearray (); AClazz = This. DefineClass (name, ByteArray, 0, bytearray.length); the                  +}Catch(FileNotFoundException e) { - e.printstacktrace (); $}Catch(IOException e) { $ e.printstacktrace (); -             }   the         } -         returnClazz;Wuyi     } the      -      Wu      Publicstring Nametopath (String className) { -StringBuffer SB =NewStringBuffer (rootdir); AboutClassName = Classname.replace ('. ', File.separatorchar) + ". Class";  $Sb.append (File.separator +className); -         returnsb.tostring (); -     } -      A}

Finally, we'll test the class we wrote:

1  Public classtest{2      Public Static voidMain (string[] args) {3         Try {4Myclassloader Myclassloader =NewMyclassloader ("F:" +file.separator+ "Workbase");5Class<?> clazz = Myclassloader.findclass ("HelloWorld");6 clazz.newinstance ();7 System.out.println (Clazz.getclassloader ());8 9}Catch(Exception e) {Ten e.printstacktrace (); One         } A     } -}

Running results: [email protected], you can see that we did use our own writing class loader.

Summary: Personal feeling understand that these should be OK, of course, see other people's blogs there are many deeper things not to say

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.