Java class loading mechanism and Tomcat class loader architecture __java

Source: Internet
Author: User
Tags thread class java web
Java class loading mechanism
class Loader

The virtual machine design team takes the "fully qualified name of a class to describe the binary byte stream" in the class loading phase to the outside of the Java Virtual Machine , so that the application can decide how to get the required class . The code module that implements this action is called the class loader.

The ClassLoader can be said to be an innovation in the Java language and one of the main reasons for the popularity of the Java language, which was originally developed to meet the needs of Java applets. Although the Java applet technology is basically "dead", but the class loader in the class level division, OSGi, thermal deployment, code encryption and other fields shine, become a Java technology system is an important cornerstone, can be said to be lost Sang, collect the east corner.

Although the ClassLoader is only used to implement the load action of a class, it plays a much more important role in Java programs than in the class loading phase. For any class, it is necessary to establish its uniqueness in the Java virtual machine, together with the class loader that loads it, and each class has a separate class namespace. This sentence can be expressed more commonly: compare two classes are "equal", only if these two classes are loaded by the same class loader only if it makes sense . Otherwise, even if these two classes originate from the same class file and are loaded by the same virtual machine, the two classes must not be equal as long as the classloader that loads them is different.


Parental delegation Model


From the Java Virtual machine perspective, there are only two different class loaders: One is the boot ClassLoader (Bootstrap ClassLoader), which is implemented using the C + + language, is part of the virtual machine itself, and the other is all the other ClassLoader, These class loaders are implemented by the Java language, independent of the virtual machine, and all inherit from the abstract class Java.lang.ClassLoader.

From the Java Developer's point of view, the ClassLoader can be divided more carefully, and most Java programs use the class loader provided by the following 3 systems.

1 start ClassLoader (Bootstrap ClassLoader): As described earlier, this class loader is responsible for storing in the \lib directory, or in the path specified by the-xbootclasspath parameter. and is recognized by the virtual machine (only by file name identification, such as Rt.jar, the name does not conform to the class library even if it is placed in the Lib directory will not be loaded) class library loaded into the virtual machine memory. The startup class loader cannot be referenced directly by the Java program .

2) Extended class loader (Extension ClassLoader): This loader is implemented by Sun.misc.Launcher.ExtClassLoader, which is responsible for loading the \lib\ext directory. Or all of the class libraries in the path specified by the JAVA.EXT.DIRS system variable, the developer can use the Extended class loader directly .

3 Application class loader (Application ClassLoader): This class loader is implemented by Sun.misc.Launcher.AppClassLoader. Because this class loader is the return value of the Getsystemclassloader () method in ClassLoader, it is generally called the System class loader. It is responsible for loading the class library specified on the user Classpath (class path), which can be used directly by the developer if the application has not customized its own classloader, which is typically the default ClassLoader in the program.

Our applications are loaded with each other by these 3 kinds of loaders, and if necessary, they can be added to their own defined ClassLoader. The relationships between these classloader are generally shown in the following illustration.


This hierarchical relationship between the class loaders shown in the figure is called the parent delegation model of the ClassLoader (Parents delegation models). The parental delegation model requires that, in addition to the top-level boot class loader, the rest of the ClassLoader should have its own parent class loader. The parent- child relationship between the ClassLoader is generally not implemented as an inheritance (inheritance) relationship, but instead uses a combination (composition) relationship to rifle through the parent loader's code. The parent delegation model of the ClassLoader was introduced during JDK 1.2 and is widely used in almost all Java programs, but it is not a mandatory constraint model, but rather a ClassLoader implementation method that Java designers recommend to developers.

The parent delegation model works by: If a class loader receives a request for class loading, it first does not attempt to load the class itself, but instead delegates the request to the parent ClassLoader, which is true for each class loader . Therefore, all load requests should eventually be routed to the top-level boot class loader, and the child loader will attempt to load itself only if the parent loader has feedback that it cannot complete the load request (its search scope does not find the required class) .

The obvious benefit of organizing the relationship between class loaders using the parental delegation model is that the Java class has a hierarchical relationship with its class loader with precedence. For example, Class Java.lang.Object, which is stored in Rt.jar, regardless of which class loader is loading the class, is ultimately delegated to the boot class loader at the top of the model to load, so the Object class is the same class in the various ClassLoader environments of the program. Conversely, if the parent delegation model is not used and is loaded by the class loader itself, if the user writes a class called Java.lang.Object and puts it in the program's class path, there will be several different object classes in the system. The most fundamental behavior in the Java type System is not guaranteed, and the application will become a mess. If the reader is interested, you can try to write a Java class that has the same name as the one in the Rt.jar class library, and you will find that it can be compiled normally, but never be loaded.

The parental delegation model is important to ensure the stability of the Java program, but its implementation is very simple, and the code that implements the parental delegation is concentrated in the Java.lang.ClassLoader LoadClass () method, as the following code shows, the logic is clear and understandable:

Protected synchronized class<?> loadclass (String name, Boolean resolve)
throws ClassNotFoundException
{
	//First, check that the requested class has been loaded
	Class C=findloadedclass (name);
	if (c== null) {
		try{
			if (parent!= null) {
				c = parent.loadclass (Name,false);
			} else {
				c = Findbootstra Pclassornull (name);
			}
		catch (ClassNotFoundException e) {
		//if the parent class loader throws ClassNotFoundException
		//Description The Parent class loader cannot complete the load request
		}
		if (c = = null) {
			////
			Findclass method for class loading
			c = Findclass (name) when
	the parent loader is unable to load; 
	if (resolve) {
		resolveclass (c);
	}
	return c;
}

Check to see if it has already been loaded, call the parent loader's LoadClass () method if it is not loaded, and use the Startup class loader as the parent loader by default if the parent loader is empty. If the parent class fails to load, the ClassNotFoundException exception is thrown, then the Findclass () method is invoked to load it. The specific logic of parental delegation is implemented in this loadclass () method, and after JDK 1.2 the user is not encouraged to overwrite the LoadClass () method, but to write its own class load logic into the Findclass () method, LoadClass () In the logic of the method, if the parent class fails to load, its own Findclass () method is invoked to complete the load, which guarantees that the newly-written class loader conforms to the parental delegation rule.


Breaking the parental delegation model


The parent delegation model mentioned above is not a mandatory constraint model, but rather a ClassLoader implementation method that Java designers recommend to developers . Most ClassLoader in the Java world follow this model, but there are exceptions.

A "corrupted" parent delegation model is caused by a flaw in the model itself, and parental delegation solves the unified problem of the underlying class of the various ClassLoader (the more basic class is loaded by the higher-level loader), and the underlying class is called the "base". Because they are always used as APIs that are invoked by user code, things are often not absolutely perfect, and what to do if the underlying class calls back to the user's code . This is not impossible, a typical example is the Jndi service, Jndi is now a standard Java service, and its code is loaded by the boot ClassLoader (in the JDK Rt.jar in 1.3, but the purpose of Jndi is to centrally manage and find resources, and it needs to invoke the Jndi interface provider that is implemented by independent vendors and deployed under the application's class path (Spi,service Provider Interface) code, but it is not possible for the startup ClassLoader to "recognize" the code because the user application class is not found in the search scope of the startup ClassLoader. To solve this problem, the Java design team had to introduce a less elegant design: The Thread Context class loader (ClassLoader). This class loader can be set through the Setcontextclassloader () method of the Java.lang.Thread class, and if it is not set when the thread is created, it inherits one from the parent thread if it is not set in the global scope of the application. The class loader defaults to the Application class loader (application ClassLoader).

With the thread context class loader, you can do some "corrupt" things, and the Jndi service uses this thread context ClassLoader to load the desired SPI code, which is the parent class loader requesting the subclass loader to complete the class loading action . This behavior is actually through the hierarchical structure of the parental delegation model to reverse the use of the ClassLoader, in fact, has violated the parental delegation model of the general principles, but this is also a helpless thing. All load actions in Java that involve SPI are basically in this way, such as Jndi, JDBC, JCE, JAXB, and Jbi.

Another "breach" of the parental delegation model is due to the user's pursuit of program dynamics, where the term "dynamic" refers to some of the current very "hot" nouns: code heat substitution (hotswap), Module thermal Deployment (hotdeployment), etc. Plainly is the hope that the application can be like our computer peripherals, connect the mouse, u disk, without restarting the machine can be used immediately , the mouse has problems or to upgrade the mouse, without downtime and restart. For a personal computer, restarting is not a big deal, but for some production systems, a shutdown reboot may be classified as a production accident, where hot deployment is a great attraction for software developers, especially enterprise-class software developers . Sun's JSR-294 and JSR-277 specifications have lost to JSR-291 in the battle of modular norms with JCP organizations (ie, OSGi R4.2), although Sun is unwilling to lose the power of Java modularity, independent in the development of jigsaw projects, but currently OSGi has become the industry "de facto" Java modular standard, and OSGI implementation of modular thermal deployment is the key to its custom classloader mechanism implementation. Each program module (called Bundle in OSGi) has a class loader of its own that replaces bundle with the same loader when a bundle is needed to implement hot-swap code.

In an OSGi environment, the ClassLoader is no longer a tree structure in the parental delegation model, but is further developed into a more complex network structure, and when a class load request is received, OSGi searches in the following order:

1 The class that begins with java.* is delegated to the parent class loader to load.

2) Otherwise, delegate the class in the list of delegated lists to the parent class loader to load.

3 Otherwise, the class in the import list is delegated to the bundle ClassLoader of this class of export.

4 Otherwise, find the current bundle class Path and load it with your own classloader.

5) Otherwise, the lookup class is in its own fragment bundle, and if it is, it is delegated to the class loader fragment bundle.

6 Otherwise, find the bundle of the dynamic import list and delegate to the class loader corresponding to the bundle load.

7 Otherwise, class lookup fails.

Only the first two points in the lookup order are still compliant with the parental delegation rule, and the rest of the class lookup is done in a peer class loader.

As long as there is enough meaning and reason to break the existing principles can be regarded as an innovation. Just as the class loader in OSGi does not conform to the traditional parent-delegated class loader, and there's a lot of controversy about the extra complexity of the industry for hot deployment, but there's a basic consensus among Java programmers: the use of ClassLoader in OSGi is well worth learning, and the implementation of OSGi is understood. , you can grasp the essence of the class loader.


Tomcat's class loader schema

The mainstream Java Web servers (that is, web containers), such as Tomcat, Jetty, WebLogic, WebSphere, or other servers not enumerated by the authors, implement their own defined classloader (more often than not). Because of a full-featured web container, there are several issues to address:

1 The Java class libraries used by the two Web applications deployed on the same Web container can be isolated from each other . This is the most basic requirement that two different applications may rely on different versions of the same Third-party class library and cannot require a class library to have only one copy of a single server, and the server should ensure that the class library of two applications can be used independently of each other.

2 The Java class libraries that are used by the two Web applications deployed on the same Web container can be shared with each other. This demand is also very common, for example, a user might have 10 applications deployed on the same server using the spring organization, and if 10 of spring is stored separately in the isolation directory of each application, it would be a huge waste of resources-largely not a waste of disk space, but The class library is loaded into the Web container's memory when it is used, and if the class library is not shared, the virtual machine's method area is prone to excessive risk of bloat .

3 The Web container needs to be as secure as possible from the Web application that is deployed. Currently, there are many mainstream Java Web containers that are themselves implemented using the Java language . As a result, the Web container itself has a problem with class library dependencies, and generally, for security reasons, the class libraries used by the container should be independent of the application's class library.

4 The Web container that supports JSP application, most need to support hotswap function. We know that the JSP file will eventually be compiled into Java class can be executed by the virtual machine, but the JSP file because of its characteristics of pure text storage, run-time modification of the probability is far greater than the third party class library or program itself class files . and ASP, PHP and JSP These Web applications also make changes do not need to restart as a great "advantage" to see , so "mainstream" web container will support the JSP generation class heat replacement , of course, there are "Non-mainstream", If the WebLogic server running in production mode (Production mode) does not handle changes to the JSP file by default.

Because of the above problems, when deploying Web applications, a separate class path is not enough, so the various web capacity "invariably" provides several classpath paths for users to store third party libraries , which are generally "lib" or " Classes

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.