编程知识 cdmana.com

Interviewer: is Tomcat a symbolic parent delegation mechanism?

I was asked this question in an interview , Now that you've asked this question , The answer is yes and No , Get to the point , Need to figure out what parental delegation is .

Class loading mechanism

ClassLoader It's used to load Class Of . It will be responsible for Class In the form of bytecode to memory Class object .

Bytecode can come from disk files *.class, It can also be jar In the bag *.class, It can also come from a byte stream provided by a remote server , The essence of bytecode is an array of bytes []byte, It has a specific complex internal format .

JVM There will be multiple ClassLoader, Different ClassLoader Bytecode files are loaded from different places . In order to prevent

JVM Parents delegate

Load custom classes User.class

 picture

for example : Customize a MyClassLoader Class loader , load com.monkeyjava.demo.User.class class . The custom class loader received a request for class loading , It does not load itself, but delegates the request to the loader of the parent class , If the parent loader still exists , Then further entrust , Such a recursive , The request eventually reaches the top-level boot loader , If the parent class can load , Then return directly , If the parent class can't load, the child class will load , Final User.class Will be loaded by the custom loader .

  load java.lang.Ojbect.class technological process

 picture

This situation , Even if we write one ourselves java.lang.Object class , Due to the parental delegation mechanism , To the top loader will load jdk Their own Object class , Instead of loading our own , This ensures Java The core API Security , Can't be tampered with .

BootstrapClassLoader( Start class loader )

Responsible for loading JVM Runtime core classes , load System.getProperty("sun.boot.class.path") The specified path or jar

ExtensionClassLoader

Responsible for loading JVM The extension class , such as swing series 、 Built in js engine 、xml Parser wait , These libraries are usually named as javax start , Their jar Package is located in the JAVAHOME/lib/rt.jar In file . load System.getProperty("java.ext.dirs") The specified path or jar.

AppClassLoader

AppClassLoader It's the loader directly facing our users , It will load. Classpath In the path defined in the environment variable jar Packages and directories .

The code we write and the third party we use jar Packages are usually loaded by it .

load System.getProperty("java.class.path") The specified path or jar.

Tomcat Class loading

Tomcat As a Web Containers need to meet the following requirements .

Tomcat It's a web Containers can deploy multiple applications , It is necessary to ensure that the class libraries in each application are isolated from each other

give an example : for example , Now there are two applications app1、app2 All deployed tomcat In the container , If app1 and app2 There are com.monkeyjava.demo.User.class class , But the functions of the two classes are completely different , If you use parental delegation , Who does the parent loader load ? Load one of the , The other must be wrong .

Two deployed on the container Web What the application uses Java Class libraries can be shared with each other .

such as jdk At the heart of jar package , otherwise , If the server has n Applications , Then there must be n Load the same class library into the virtual machine .

Web Containers need to be safe from Web Application impact ,tomcat lib There are a lot of dependencies jar, It needs to be guaranteed against its web Impact of application .• Support JSP The container of , Need to support hot deployment capabilities

We think about how we can achieve jsp Hot revision of documents ( The name of the building owner ),jsp The document is actually class file , So if it changes , But the class name is the same , Class loader will directly take the existing in method area , The modified jsp It won't reload . So what to do ? We can uninstall this directly jsp Class loader for files , So you should think of , Every jsp The file corresponds to a unique classloader , When one jsp The file has been modified , Just uninstall this jsp Class loader . Recreate class loader , Reload jsp file .




Tomcat How to design a class loader

The above needs are destined to tomcat It is impossible to use simple ClassLoader Complete class loading , You need to define hierarchical class loading ,Tomcat In order to solve the above loading problems , Made a great design .

 picture

stay Tomcat in , Defined 3 Group directory structure /common/*,/server/* and /shared/* It can store Java Class library , And then there is Web The structure of the application itself :/WEB-INF/*, These directory structures correspond to different loaders

common:  Class libraries can be Tomcat And all Web Applications work together , from CommonClassLoader load .server:  Class libraries can be Tomcat Use , For others Web The program is not visible , from CatalinaClassLoader load .shared:  Class libraries can be used by all Web Applications work together , But yes Tomcat invisible , from SharedClassLoader.**WEB-INF: ** A class library can only be used by itself Web Application usage , from WebappClassLoader load

among WebApp Class loader and Jsp Class loaders usually have multiple instances , every last Web Applications Corresponding to one WebApp Class loader , every last JSP The file corresponds to a Jsp Class loader .

As can be seen from the relationship above

1.

CommonClassLoader All classes that can be loaded can be Catalina ClassLoader and SharedClassLoader Use , Thus, the sharing of public class libraries is realized , and CatalinaClassLoader and Shared ClassLoader Classes that you can load are isolated from each other .

2.

WebAppClassLoader have access to SharedClassLoader Class loaded , But each WebAppClassLoader Instances are isolated from each other .

3.

and JasperLoader The loading range of is just this JSP The one compiled by the file .Class file , It appears for the purpose of being discarded : When Web The container detected JSP When the document is modified , Will replace the current JasperLoader Example , And by building a new Jsp Class loader to achieve JSP Of documents HotSwap function .




WebAppClassLoader

WebAppClassLoader Breaking the parental trust mechanism , It first tries to load a class itself , If no more proxies are found for the parent loader , The goal is to load... First Web Apply your own defined classes . The concrete implementation is to rewrite ClassLoader Two approaches :findClass and loadClass.

findClass Method

public Class<?> findClass(String name) throws ClassNotFoundException {
...

Class<?> clazz = null;
try {
//1. First in Web Application directory to find the class
clazz = findClassInternal(name);
} catch (RuntimeException e) {
throw e;
}

if (clazz == null) {
try {
//2. If not found in the local directory , Give it to the parent loader to find
clazz = super.findClass(name);
} catch (RuntimeException e) {
throw e;
}

//3. If the parent class is not found , Throw out ClassNotFoundException
if (clazz == null) {
throw new ClassNotFoundException(name);
}

return clazz;
}

stay findClass In the method , There are three main steps :1、 First in Web Use the local directory to find the class to load .2、 If not found , Give it to the parent loader to find . 3、 How can the parent loader not find this class , Throw out ClassNotFound abnormal .

loadClass Method

public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {

synchronized (getClassLoadingLock(name)) {

Class<?> clazz = null;

//1. First, locally cache Find out if the class has been loaded
clazz = findLoadedClass0(name);
if (clazz != null) {
if (resolve)
resolveClass(clazz);
return clazz;
}

//2. From the system class loader cache To find out if
clazz = findLoadedClass(name);
if (clazz != null) {
if (resolve)
resolveClass(clazz);
return clazz;
}

// 3. Try to use ExtClassLoader Class loader class loading , Why? ?
ClassLoader javaseLoader = getJavaseClassLoader();
try {
clazz = javaseLoader.loadClass(name);
if (clazz != null) {
if (resolve)
resolveClass(clazz);
return clazz;
}
} catch (ClassNotFoundException e) {
// Ignore
}

// 4. Try searching the local directory for class And load
try {
clazz = findClass(name);
if (clazz != null) {
if (resolve)
resolveClass(clazz);
return clazz;
}
} catch (ClassNotFoundException e) {
// Ignore
}

// 5. Try using the system class loader ( That is to say AppClassLoader) To load the
try {
clazz = Class.forName(name, false, parent);
if (clazz != null) {
if (resolve)
resolveClass(clazz);
return clazz;
}
} catch (ClassNotFoundException e) {
// Ignore
}
}

//6. All of the above processes failed to load , Throw an exception
throw new ClassNotFoundException(name);
}




 ```

loadClass The method is a little more complicated , There are six main steps :
1、 First, locally Cache Find out if the class has been loaded , in other words Tomcat Whether the class loader of has already loaded this class .
2、 If Tomcat The class loader has not loaded this class , Let's see if the system class loader has been loaded .
3、 If not , let ExtClassLoader To load the , This is the key step , Purpose prevention Web Apply your own class overlay JRE The core of the class . because Tomcat We need to break the parental trust mechanism , If Web The app has a custom called Object Class , If you load this first Object class , It will cover JRE The one inside Object class , That's why Tomcat The class loader of will first try to use ExtClassLoader To load the , because ExtClassLoader Will be entrusted to BootstrapClassLoader To load the ,BootstrapClassLoader Find yourself loaded Object class , Direct return to Tomcat Class loader for , such Tomcat The class loader will not load Web Under the application of Object The class , So we can avoid coverage JRE The core class problem .
4、 If ExtClassLoader Loader failed to load , in other words JRE There is no such class in the core class , So it's local Web Find and load in the application directory .
5、 If there is no such class in the local directory , The explanation is not Web Apply your own defined classes , Then the system class loader will load . Here, please pay attention to ,Web The application is through Class.forName Class loader to the system call , because Class.forName The default loader of is the system class loader .
6、 If all of the above loading processes fail , Throw out ClassNotFound abnormal .

summary

Tomcat Contrary to java Is the recommended parent delegation model available ? The answer is : Contrary to !

Parent delegation principle " The parental delegation model requires that in addition to the top-level boot loader , The rest of the class loaders should be loaded by their own parent class loaders ."

Obviously ,tomcat Not so ,tomcat To achieve isolation , Didn't abide by the agreement , Every WebAppClassLoader Load... In your own directory class file , Will not be passed to the parent loader .


 

 picture

Focus on ” Brother monkey said Java“ Get more dry goods

版权声明
本文为[Monkey said Java]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/10/20211002145641041T.html

Scroll to Top