Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the parental appointment mechanism?

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the knowledge of "what is the parental appointment mechanism". In the operation of actual cases, many people will encounter such a dilemma. Then let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

What is the parent delegation mechanism? first of all, we know that a virtual machine needs to use a class loader to load a class, but in Java, there are many class loaders, so when JVM wants to load a .class file, which class loader should load it? This has to mention the "parent appointment mechanism". First of all, we need to know that the following four types of loaders are supported in Java language systems: BootstrapClassLoader startup class loader, Extention ClassLoader standard extension class loader, Application ClassLoader application class loader, User ClassLoader user-defined class loader, there is a hierarchical relationship between these four kinds of loaders. The following figure shows that the upper layer loader is generally considered as the parent loader of the next layer loader, so, in addition to BootstrapClassLoader All loaders have parent loaders.

So, the so-called parent delegation mechanism means that when a class loader receives a request for class loading, it will not load the specified class directly, but delegate the request to its parent loader to load. The current loader is responsible for loading the class only if the parent loader cannot load the class. So, under what circumstances will the parent loader fail to load a class? In fact, these four types of loaders provided in Java have their own responsibilities: Bootstrap ClassLoader, which is mainly responsible for loading the Java core class library, rt.jar, resources.jar, charsets.jar and class under% JRE_HOME%\ lib. Extention ClassLoader, which is mainly responsible for loading jar packages and class files in the directory% JRE_HOME%\ lib\ ext. Application ClassLoader, mainly responsible for loading all classes User ClassLoader under the classpath of the current application, user-defined class loader, can load class files with specified paths, that is to say, a user-defined class, such as com.hollis.ClassHollis, will not be loaded by Bootstrap and Extention loaders anyway.

Why do parents need to be appointed? As we mentioned above, because there is a strict hierarchical relationship between class loaders, the Java class also has a hierarchical relationship. Or this hierarchical relationship is a priority. For example, a class defined under the java.lang package, because it is stored in rt.jar, is summarized in the loading process and is delegated all the way to Bootstrap ClassLoader, which is finally loaded by Bootstrap ClassLoader. A user-defined com.hollis.ClassHollis class will also be delegated to Bootstrap ClassLoader, but because Bootstrap ClassLoader is not responsible for loading the class, Extention ClassLoader will try to load it, and Extention ClassLoader will not be responsible for loading the class, so it will eventually be loaded by Application ClassLoader. This mechanism has several advantages. First of all, by delegating, you can avoid repeated loading of the class, and when the parent loader has already loaded a class, the child loader will not reload the class. In addition, the security is ensured by the way of parents' appointment. Because when Bootstrap ClassLoader loads, only the classes in the jar package in JAVA_HOME, such as java.lang.Integer, will not be replaced at will, unless someone runs to your machine and destroys your JDK. In that case, you can prevent someone from customizing a destructive java.lang.Integer to be loaded. This can effectively prevent the core Java API from being tampered with.

Is the relationship between father and son loaders inherited? Many people think that there is an inheritance relationship between classloaders in Java when they see names such as parent loaders and child loaders. Even many articles on the Internet have similar erroneous views. To be clear here, in the parent delegation model, the parent-child relationship between class loaders is generally not implemented as an Inheritance relationship, but rather a Composition relationship is used to reuse the code of the parent loader. The following is the definition of the parent loader in ClassLoader:

Public abstract class ClassLoader {

/ / The parent class loader for delegation

Private final ClassLoader parent

}

How is parental appointment realized? The parental delegation model is very important to ensure the stable operation of the Java program, but its implementation is not complicated. The code that implements the parent delegation is concentrated in the loadClass () method of java.lang.ClassLoader:

Protected Class loadClass (String name, boolean resolve)

Throws ClassNotFoundException

{

Synchronized (getClassLoadingLock (name)) {

/ / First, check if the class has already been loaded

Class c = findLoadedClass (name)

If (c = = null) {

Long T0 = System.nanoTime ()

Try {

If (parent! = null) {

C = parent.loadClass (name, false)

} else {

C = findBootstrapClassOrNull (name)

}

} catch (ClassNotFoundException e) {

/ / ClassNotFoundException thrown if class not found

/ / from the non-null parent class loader

}

If (c = = null) {

/ / If still not found, then invoke findClass in order

/ / to find the class.

Long T1 = System.nanoTime ()

C = findClass (name)

/ / this is the defining class loader; record the stats

Sun.misc.PerfCounter.getParentDelegationTime () .addTime (T1-t0)

Sun.misc.PerfCounter.getFindClassTime () .addElapsedTimeFrom (T1)

Sun.misc.PerfCounter.getFindClasses () .increment ()

}

}

If (resolve) {

ResolveClass (c)

}

Return c

}

}

The code is not difficult to understand, mainly in the following steps:

1. First check whether the class has been loaded. 2. If not, call the loadClass () method of the parent loader to load 3. If the parent loader is empty, the startup class loader is used as the parent loader by default. 4. If the parent class fails to load, after throwing a ClassNotFoundException exception, call your own findClass () method to load.

How to take the initiative to destroy the parent appointment mechanism? Knowing the implementation of the parent delegation model, it is easy to break the parent delegation mechanism. Because his parent delegation process is implemented in the loadClass method, if you want to break this mechanism, customize a class loader and override the loadClass method in it so that it does not perform parent delegation.

There are many ways for loadClass (), findClass (), and defineClass () to distinguish between ClassLoader and class loading. LoadClass was mentioned earlier. In addition, there are findClass and defineClass, so what's the difference between these methods? LoadClass () is the main method for class loading, and the default parent delegation mechanism is implemented in this method. FindClass () loads .class bytecode definclass () to convert bytecode to Class based on name or location, which requires a little bit about loadClass and findClass. As we said earlier, when we want to customize a class loader, and like breaking the principle of parental delegation, we rewrite the loadClass method. So, what if we want to define a classloader but don't want to break the parent delegate model? At this point, you can inherit ClassLoader and override the findClass method. The findClass () method is a new addition to ClassLoader after JDK1.2.

/ * *

* @ since 1.2

, /

Protected Class findClass (String name) throws ClassNotFoundException {

Throw new ClassNotFoundException (name)

}

This method throws only one exception and has no default implementation.

JDK1.2 no longer encourages users to directly override the loadClass () method, but instead suggests implementing their own class loading logic into the findClass () method. Because in the logic of the loadClass () method, if the parent class loader fails to load, it will call its own findClass () method to complete the load. So, if you want to define your own classloader and follow the parent delegation model, you can inherit ClassLoader and implement your own loading logic in findClass.

The destruction of parental delegation mechanism is not uncommon. Many frameworks, containers, and so on will destroy this mechanism to achieve some functions. The first situation that is destroyed is before the emergence of parental appointments. Since the parent delegation model was introduced after JDK1.2, user-defined classloaders were already in use. Therefore, these do not abide by the principle of parental appointment. The second is when JNDI, JDBC, and so on need to load the SPI interface implementation class. The third is to implement hot-swappable hot deployment tools. In order to make the code work dynamically without restarting, the hot replacement of the code is realized by replacing the module with similar loaders. The fourth is the emergence of tomcat and other web containers. The fifth is the application of OSGI, Jigsaw and other modular technologies.

Why do JNDI,JDBC and others need to sabotage parental appointments? Most of the time in our daily development, we will call the basic classes provided by Java through API, and these basic classes are loaded by Bootstrap. However, in addition to API, there is also a way of SPI. Like a typical JDBC service, we usually create a database connection by: Connection conn = DriverManager.getConnection ("jdbc:mysql://localhost:3306/mysql", "root", "1234")

Before the above code is executed, DriverManager will be loaded by the classloader, because the java.sql.DriverManager class is located under rt.jar, so it will be loaded by the root loader.

When the class is loaded, the static methods of the class are executed. There is a key piece of code: ServiceLoader loadedDrivers = ServiceLoader.load (Driver.class)

This code attempts to load all the implementation classes under classpath that implement the Driver interface.

So, here comes the problem. DriverManager is loaded by the root loader, so if you encounter the above code during loading, you will try to load all the implementation classes of Driver, but these implementation classes are basically provided by third parties, and according to the principle of parent delegation, third party classes cannot be loaded by the root loader. So, how to solve this problem? As a result, the parental delegation principle is broken by introducing ThreadContextClassLoader (thread context loader, AppClassLoader by default) in JDBC. If we go deep into the ServiceLoader.load method, we can see: public static ServiceLoader load (Class service) {

ClassLoader cl = Thread.currentThread () .getContextClassLoader ()

Return ServiceLoader.load (service, cl)

}

The first line gets the current thread's thread up and down the class loader AppClassLoader, which loads the concrete implementation class in the classpath.

Why Tomcat destroys parent delegation We know that Tomcat is a web container, so a web container may need to deploy multiple applications. Different applications may rely on different versions of the same third-party class library, but the full path name of a class in different versions of the class library may be the same. For example, many applications rely on hollis.jar, but An application depends on version 1.0.0, but B application depends on version 1.0.1. One of the classes in both versions is com.hollis.Test.class. If you use the default parent delegate class loading mechanism, you cannot load multiple identical classes. Therefore, Tomcat breaks the principle of parental delegation and provides a mechanism for isolation, providing a separate WebAppClassLoader loader for each web container. Tomcat's class loading mechanism: in order to achieve isolation, priority is given to loading classes defined by the Web application, so each application's own class loader, WebAppClassLoader, is responsible for loading the class files in its own directory, and then give it to CommonClassLoader to load when it fails to load, which is just the opposite of parental delegation.

Modularization technology and class loading mechanism have been very mature in recent years, and modularization technology has been applied in JDK 9. In fact, before JDK 9, the framework of OSGI was already modular, and the precise control of module hot plug and module internal visibility by OSGI is attributed to its special class loading mechanism. The relationship between loaders is no longer the tree structure of the parent delegation model, but develops into a complex mesh structure. In JDK, parental assignments are not absolute. Before JDK9, the basic classes of JVM used to be in the rt.jar package, which is also the cornerstone of JRE operation. This is not only a violation of the principle of single responsibility, but also a lot of useless classes will be packaged when compiling, resulting in bloated. In JDK9, the whole JDK is built based on modularization. The previous rt.jar and tool.jar are divided into dozens of modules. When compiling, only the modules actually used are compiled. At the same time, each class loader does its own job and only loads the modules that it is responsible for.

Class c = findLoadedClass (cn)

If (c = = null) {

/ / find out which module the current class belongs to

LoadedModule loadedModule = findLoadedModule (cn)

If (loadedModule! = null) {

/ / get the class loader of the current module

BuiltinClassLoader loader = loadedModule.loader ()

/ / perform class loading

C = findClassInModuleOrNull (loadedModule, cn)

} else {

/ / parent delegation will be made only if the module information is not found.

If (parent! = null) {

C = parent.loadClassOrNull (cn)

}

}

}

This is the end of the content of "what is the parent appointment mechanism". Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report