In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
I believe many inexperienced people don't know what to do about how to use the class loader in Tomcat. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.
Class loader in Tomcat
Before we learn about the classloader in Tomcat and why Tomcat implements its own classloader to break the parent delegate model, we first need to know what the classloader defined in Java is and what the parental delegate model is.
Class loader in Java
The classloader is responsible for dynamically loading java files into JVM when the program is running.
From the perspective of the Java virtual machine, there are two different types of classloaders:
Launch classloader (Bootstrap ClassLoader): this classloader is implemented in the C++ language and is part of the virtual machine itself.
Other class loaders: these class loaders are implemented in the Java language, independent of the virtual machine, and all inherit from the abstract class java.lang.ClassLoader. Other class loaders are probably divided into
ExtensionClassLoader: this class loader is implemented by ExtClassLoader and is responsible for loading all classes in the JAVA_HOME/lib/ext directory or in the path specified by the java.ext.dir system variable.
ApplicationClassLoader: this classloader is implemented by AppClassLoader and is responsible for loading all the classes specified on the user classpath (ClassPath). If the application does not customize its own classloader, it is generally the default classloader in the program.
Custom loader: customize the loader that loads a specific path according to your own needs.
For any class, the class loader that loads it and the class itself need to establish its uniqueness in the Java virtual machine.
Parental delegation model
The hierarchy shown in the figure above is called the parent delegation model of the class loader. The parent delegation model requires that all loaders, except the top-level startup class loader, have their own parent loaders. The parent-child relationship here is not achieved by inheritance, but by setting the parent variable.
The working process of the parent delegation model is that if you receive a request for a class load, it will not load the class first, but will first delegate the request to the parent class loader to complete, each level until the startup class loader, only the parent class does not load this file, then the subclass will try to load it itself.
Why set up a parent delegation model? In fact, it is to ensure the stable operation of the Java program, such as the Object class, which is stored in rt.jar, no matter which class loader wants to load the Object class, it will eventually be delegated to the top-level BootStrapClassLoader, so the Object used in all classes is the same class, on the contrary, if there is no parent delegation model, then a random class loader can define a new Object class, then the application will become very chaotic. In fact, the parental delegation model code is very simple. The implementation is under the loadClass method in ClassLoader.
Protected Class loadClass (String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock (name)) {/ / first, check whether the request class has been loaded with Class c = findLoadedClass (name); if (c = = null) {long t0 = System.nanoTime () Try {/ / if it has not been loaded by this class loader, first delegate the parent class to load if (parent! = null) {c = parent.loadClass (name, false) } else {/ / if there is no parent class, it means that at the top level, it will be handed over to the BootStrap classloader to load c = findBootstrapClassOrNull (name) } / / if the topmost class cannot be found, a ClassNotFoundException exception will be thrown} catch (ClassNotFoundException e) {} / / if none of the parent classes have loaded this class, the subclass will start loading such if (c = = null) {c = findClass (name) }} if (resolve) {resolveClass (c);} return c;}} protected Class findClass (String name) throws ClassNotFoundException {throw new ClassNotFoundException (name);}
We can see that the findClass method is the logic that needs to be implemented by the subclass itself.
Class loader in Tomcat
The following diagram is a diagram of the Tomcat classloader given in the official documentation for the Tomcat9 version.
Bootstrap | System | Common /\ Webapp1 Webapp2..
Bootstrap: the highest loader for Java, implemented in C language, is mainly used to load core classes needed for JVM startup, such as classes under the $JAVA_HOME/jre/lib/ext path.
System: all classes of the path defined by the CLASSPATH system variable are loaded.
Common: all classes under the lib file under the Tomcat path are loaded.
Webapp1, Webapp2. : all classes in the project under the webapp path are loaded. A project corresponds to a WebappClassLoader, thus achieving class isolation between applications.
These three parts are reflected in the above Java parent delegation model diagram. However, you can see that ExtClassLoader is not drawn, which can be understood as merging with bootstrap and loading classes under JAVA_HOME/jre/lib. So why does Tomcat customize the classloader?
Isolate different applications: different applications An and B deployed in the same Tomcat, for example, A uses Spring2.5. B uses Spring3.5, so if the two applications use the same class loader, then the Web application will not start because of the jar package coverage.
Flexibility: class loaders between Web applications are independent of each other, so different class loaders can be rebuilt according to different files modified. So as not to affect other applications.
Performance: if multiple applications are deployed in one Tomcat, there are the same class library dependencies in multiple applications. Then you can have the same class library loaded by the Common class loader.
Tomcat customizes the WebAppClassLoader classloader. Break the mechanism of parental delegation, that is, if you receive a request for class loading, you will try to load it yourself, and if you can't find it, give it to the parent loader to load, in order to give priority to loading the class defined by the Web application. We know that ClassLoader's default loadClass method loads classes based on a parental delegated model, so since Tomcat wants to break this rule, it is necessary to override the loadClass method. We can look at the overridden loadClass method in the WebAppClassLoader class.
@ Overridepublic Class loadClass (String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock (name)) {Class clazz = null; / / 1. Find out from the local cache whether such clazz = findLoadedClass0 (name); if (clazz! = null) {if (log.isDebugEnabled ()) log.debug ("Returning class from cache"); if (resolve) resolveClass (clazz); return clazz;} / / 2. Find out from AppClassLoader whether such clazz = findLoadedClass (name); if (clazz! = null) {if (log.isDebugEnabled ()) log.debug ("Returning class from cache"); if (resolve) resolveClass (clazz); return clazz;} String resourceName = binaryNameToPath (name, false); / / 3. Try to load the class with the ExtClassLoader classloader to prevent Web applications from overwriting JRE's core class ClassLoader javaseLoader = getJavaseClassLoader (); boolean tryLoadingFromJavaseLoader; try {URL url; if (securityManager! = null) {PrivilegedAction dp = new PrivilegedJavaseGetResource (resourceName); url = AccessController.doPrivileged (dp);} else {url = javaseLoader.getResource (resourceName) } tryLoadingFromJavaseLoader = (url! = null);} catch (Throwable t) {tryLoadingFromJavaseLoader = true;} boolean delegateLoad = delegate | | filter (name, true); / / 4. Determine whether the delegate property is set, and if set to true, then load the class if (delegateLoad) {if (log.isDebugEnabled ()) log.debug ("Delegating to parent classloader1" + parent) according to the parent delegation mechanism; try {clazz = Class.forName (name, false, parent) If (clazz! = null) {if (log.isDebugEnabled ()) log.debug ("Loading class from parent"); if (resolve) resolveClass (clazz); return clazz }} catch (ClassNotFoundException e) {/ / Ignore} / / 5. If delegate is set to false by default, if (log.isDebugEnabled ()) log.debug ("Searching local repositories") will be loaded with WebAppClassLoader first; try {clazz = findClass (name); if (clazz! = null) {if (log.isDebugEnabled ()) log.debug ("Loading class from local repository") If (resolve) resolveClass (clazz); return clazz;}} catch (ClassNotFoundException e) {/ / Ignore} / / 6. If no class is found in WebAppClassLoader at this time, delegate AppClassLoader to load if (! delegateLoad) {if (log.isDebugEnabled ()) log.debug ("Delegating to parent classloader at end:" + parent); try {clazz = Class.forName (name, false, parent) If (clazz! = null) {if (log.isDebugEnabled ()) log.debug ("Loading class from parent"); if (resolve) resolveClass (clazz); return clazz } catch (ClassNotFoundException e) {/ / Ignore} throw new ClassNotFoundException (name);}
Finally, to borrow the words on the official website of Tomcat:
The default class loading order for Web applications is (breaking the parent delegation rule):
Load it from the BootStrapClassLoader of JVM first.
Load the classes in / WEB-INF/classes under the Web application.
Load the classes in the jar package in / WEB-INF/lib/*.jap under the Web application.
Load the classes under the System path defined above.
Load the classes under the Common path defined above.
If it is configured in the configuration file, the parent delegation rules are followed, and the loading order is as follows:
Load it from the BootStrapClassLoader of JVM first.
Load the classes under the System path defined above.
Load the classes under the Common path defined above.
Load the classes in / WEB-INF/classes under the Web application.
Load the classes in the jar package in / WEB-INF/lib/*.jap under the Web application.
After reading the above, have you mastered how to use the classloader in Tomcat? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.