Java class loader and java Class Loader

Source: Internet
Author: User

Java class loader and java Class Loader

The Java Class loader is a very important concept. I have always wanted to write a blog about it. Today I have read many other people's blogs and want to write about it, hope you can understand it.

 

First, understand the concept of the Class Loader:

As the name implies, the class loader is used to load Java classes into Java virtual machines. Generally, Java virtual machines use Java classes as follows: Java source programs (. java files) are converted to Java Byte Code (. class files) after being compiled by the Java compiler ). The Class Loader reads the Java byte code and converts itjava.lang.ClassClass. Each such instance is used to represent a Java class. ThenewInstance()Method to create an object of this class. The actual situation may be more complex. For example, Java byte code may be dynamically generated by tools or downloaded over the network. For example, when we

There is A class A, first javac. a. java, generate. class file, at this time, and then java A, now jvm needs to load class A, it has to load to the class loader, at this time the class loader is useful, load Class A to jvm.

 

After understanding the basic concepts of the Class Loader, we will think that everything in java is an object, and the class loader is also a java class. Who will load it? ---> Jvm

When jvm is started, jre/rt is started. the class loader in jar: bootstrap classloader, used to load the java core api. Then, start the extended Class Loader ExtClassLoader to load the extension class and load the user program loader AppClassLoader, and specify ExtClassLoader as its parent class;

The class loaders in Java can be roughly divided into two types: one is provided by the system, and the other is compiled by Java application developers. The system provides the following class loaders:

  • Bootstrap class loader: it is used to load the core library of Java. It is implemented in c ++ and does not inherit fromjava.lang.ClassLoader.
  • Extensions class loader: used to load Java extension libraries. The Java virtual machine provides an extension library directory. This class loader searches for and loads Java classes in this directory.
  • System class loader: it loads Java classes according to the CLASSPATH of Java applications. Generally, Java application classes are loaded by them. You can useClassLoader.getSystemClassLoader()To obtain it.

The parent class loader of the system class loader is the extension class loader, while the parent class loader of the extension class loader is the bootstrap class loader, and the parent-parent delegation mode is used in java, --> when loading a class, BootStrap first looks for it. If it cannot be found, it will be searched by Extension ClassLoader, and finally App ClassLoader. This effectively avoids security issues.

 

Let's take a look at java. lang. classLoader class: ClassLoader is an abstract class. We can see that this class is loaded by bootstrap ClassLoader. All implementation classes (except bootstrap ClassLoader) of the Class Loader must inherit this class,

getParent() Returns the parent class loader of the class loader. If the parent classloader of this class is bootstrap classloader, null is returned.
loadClass(String name) Load Name:nameClass, the returned result isjava.lang.ClassClass.
findClass(String name) The search name isnameClass, the returned result isjava.lang.ClassClass.
findLoadedClass(String name) The search name isnameThe returned result isjava.lang.ClassClass.
defineClass(String name, byte[] b, int off, int len) Put the byte arraybAnd the returned result isjava.lang.ClassClass. This method is declaredfinal.
resolveClass(Class<?> c) Link to the specified Java class.
  1. // First, check if the class has already been loaded
  2. // JVM specifications stipulate that ClassLoader can retain the Class it loads in the cache. If a Class has been loaded, it will be obtained 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;
}

// If it has not been loaded, call the findBootstrapClass0 () method:

We can see from the above: the Class Loader loads a class. First, it uses the class name to determine whether the class has been loaded. If it has been loaded, it is directly retrieved from the cache, if it has not been loaded, use the system class loader to load it (system class loader). If it is not loaded successfully, call the findBootstrapClass0 (name) method to load it. If neither of the two methods is successful, call the findclass (String name) method to find the class.

 

Thread context Class Loader:

There are two methods in the Thread class: getContextClassLoader () and setContextClassLoader (cl); they are used to obtain and set the context class loader of the Thread.setContextClassLoader(ClassLoader cl)The thread inherits the context class loader of its parent thread. The context class loader of the initial thread of the Java application is the system class loader. (Sun. misc. Launcher $ AppClassLoader) code running in the thread can be used to load classes and resources.

The proxy mode of the Class Loader mentioned above does not solve all the problems encountered in Java application development. Java provides many Service Provider Interfaces (SPI), allowing third parties to implement these interfaces. Common SPI include JDBC, JCE, JNDI, JAXP, and JBI. These SPI interfaces are provided by the Java core library. For example, JAXP's SPI interface definition is included injavax.xml.parsersPackage. These SPI implementation codes are probably included as jar packages that Java applications depend on. They can be found through CLASSPATH, for example, implement the jar package contained in Apache Xerces of jaxp spi. The code in the SPI interface often needs to load specific implementation classes. For example, in JAXPjavax.xml.parsers.DocumentBuilderFactoryClassnewInstance()Method to generate a newDocumentBuilderFactory. The real class of the instance here is inherited fromjavax.xml.parsers.DocumentBuilderFactoryProvided by the SPI implementation. For example, in Apache Xerces, the implemented class isorg.apache.xerces.jaxp.DocumentBuilderFactoryImpl. The problem is,The SPI interface is part of the Java core library and is loaded by the boot Class Loader. the Java classes implemented by SPI are generally loaded by the system class loader. The bootstrap loader cannot find the SPI implementation class because it only loads the Java core library. It cannot be used as a proxy to the system class loader because it is the ancestor class loader of the system class loader.. That is to say, the proxy mode of the Class Loader cannot solve this problem.

The thread context loader solves this problem. If no settings are made, the context class loader of the Java application thread is the system context class loader by default. You can use the thread context class loader in the SPI interface code to successfully load the class to the SPI implementation. The thread context loader is used in many SPI implementations.

 

In fact, in Java applications, if ClassLoader is not set manually in the program, the ClassLoader obtained by the following two methods of the general java class is usually the same

This. getClass. getClassLoader ();
Thread. currentThread (). getContextClassLoader ();
The Classloader obtained by the method is static, indicating who the class loader is. The Classloader obtained by method 2 is dynamic, and the Classloader of the executor is executed by the operator (a thread. For Classes in singleton mode, static classes, etc., after being loaded once, this instance will be called by many programs (threads). For these classes, the loaded Classloader and the execution thread Classloader are usually different.

 

Class. forName

Class.forNameIs a static method and can also be used to load classes. This method has two forms:Class.forName(String name, boolean initialize, ClassLoader loader)AndClass.forName(String className). Parameters in the first formnameIndicates the full name of the class;initializeIndicates whether to initialize the class;loaderIndicates the Class Loader used for loading. The second form is equivalent to setting parameters.initializeIstrue,loaderThe value is the class loader of the current class.Class.forNameIs a common usage when loading the database driver. For exampleClass.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance()The driver used to load the Apache Derby database.

 

/******* The basic concept ends here, next, develop your own class loader ******************/

First, we need to know why we need to develop our own class loaders ,. For example, your application transmits Java-Class byte code over the network. To ensure security, these byte codes are encrypted. At this time, you need your own class loader to read the encrypted byte code from a network address, and then perform decryption and verification, finally, define the class to run in the Java Virtual Machine

The Class Loader we write is generally used to override the findClass (name) method.

Suppose we have a HelloWorld class with the following code:

1 public class HelloWorld 2 { 3 public HelloWorld() { 4 System.out.println("Test"); 5 } 6 public static void main(String[] args) { 7 System.out.println("Hello World"); 8 } 9 }  

 

At this time, we do not want the Java system class loader to load it, but our own class loader to load it, so that our class loader class inherits java. lang. classLoader class, which is implemented by ourselves

Findclass () method, step:

1: Find the class to be loaded based on the class name passed in by the constructor.

2: Use the findLoadedClass (name) method of java. lang. ClassLoader to determine whether the class exists in the cache. If the class is directly returned or not, proceed to the next step.

3: because our goal is to convert the class we want to load into byte [] array, and then use this. the defineClass (name, B, off, len) method defines the class, so we can work in this direction for the virtual machine. The code is not explained too much, and there are some java. nio. * class, will write a blog

 

 

1 public class MyClassLoader extends ClassLoader {2 3 private String rootDir; 4 5 public MyClassLoader (String rootDir) {6 this. rootDir = rootDir; 7} 8 9 10 @ Override11 protected Class <?> FindClass (String name) throws ClassNotFoundException {12 Class <?> Clazz = this. findLoadedClass (name); 13 if (clazz = null) {14 try {15 String classFile = nameToPath (name); 17 FileInputStream in = new FileInputStream (classFile ); 18 // write the target class to 19 FileChannel channels = in. getChannel (); 20 21 ByteArrayOutputStream out = new ByteArrayOutputStream (); 22 WritableByteChannel byteChannel = Channels. newChannel (out); 23 // defines a 1024 bytes buffer 24 ByteBuffer buffer = ByteBuffer. allocate (1024); 25 while (true) {27 int readNum = channel. read (buffer); 28 if (readNum =-1) {30 break; 31} 33 buffer. flip (); 34 byteChannel. write (buffer); 35 buffer. clear (); 37} 38 39 channels. close (); 40 byte [] byteArray = out. toByteArray (); 41 clazz = this. defineClass (name, byteArray, 0, byteArray. length); 42 43} catch (FileNotFoundException e) {44 e. printStackTrace (); 45} catch (IOException e) {46 e. printStackTrace (); 47} 49} 50 return clazz; 51} 52 53 54 public String nameToPath (String className) {55 StringBuffer sb = new StringBuffer (rootDir); 56 className = className. replace ('. ', File. separatorChar) + ". class "; 57 sb. append (File. separator + className); 58 return sb. toString (); 59} 60 61}

Finally, we can test the written class:

 1 public class Test{ 2     public static void main(String[] args) { 3         try { 4             MyClassLoader myclassloader = new MyClassLoader("f:"+File.separator+"workbase"); 5             Class<?> clazz = myclassloader.findClass("HelloWorld"); 6             clazz.newInstance(); 7             System.out.println(clazz.getClassLoader()); 8  9         } catch (Exception e) {10             e.printStackTrace();11         }12     }13 }

Running result: MyClassLoader @ 17609872. We can see that the class loader we wrote is used.

 

Conclusion: I personally think it should be okay to understand this. Of course, if you see other blogs, there are many more in-depth things, you won't talk about it.

 


In java, what is the class loader subsystem?

Classes in java must be loaded into jvm before they can be used. The tool that loads java classes into jvm is the class loader.
Java has three built-in loaders, BootstrapClassLoader, ExtClassLoader, and SystemClassLoader (the name may be incorrect). The first one is the class required for loading jvm startup and some basic java class libraries, which are not written in java; the other two are written in java and used to load other java classes.
Classes written by the user are generally loaded using SystemClassLoader, because the loading path is classpath, which can be set by the user. Generally, the project path is set.

How many java class loaders are there ??

Depending on the implementation, there may be countless different Loaders

However, I only know two types of file loaders: local file loaders and network loaders.

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.