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

How to implement classloader with Tomcat

2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

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

How to implement the classloader using Tomcat? Many novices are not very clear about this. In order to help you solve this problem, the following editor will explain it in detail. People with this need can come and learn. I hope you can gain something.

1. Java class loading mechanism

Class loading is to load the compiled class file into JVM memory (permanent generation / metaspace).

Class loaders can achieve class isolation because the premise that two classes are equal is that they are loaded by the same class loader, otherwise they must not be equal.

When JVM loads, it uses a parent delegate mechanism. When a class loader loads a class, the loading order is:

First delegate the request to the parent loader, if the parent loader cannot find the class to load, and then find its own repository to try to load

The advantage of this mechanism is that it ensures that the core class libraries are not overwritten.

According to the recommendations of the Servlet specification, the Webapp loader is slightly different. It will first search its own repository rather than delegate upwards, breaking the standard delegation mechanism. Let's take a look at the design and implementation of Tomcat.

2. Design of Tomcat class loader

The structure of Tomcat overall classloader is as follows:

The class loaders provided inside JDK are:

Bootstrap-boot class loader, which is part of JVM, loads a specific file in / lib/ directory Extension-extension class loader, loads class library Application-application class loader in / lib/ext/ directory, also known as system class loader, loads class libraries specified by CLASSPATH

The class loaders of the Tomcat custom implementation are:

Common-the parent loader is AppClassLoader, and the class library Catalina in the ${catalina.home} / lib/ directory loads by default-the parent loader is the Common classloader, which loads the resources configured by server.loader in the catalina.properties configuration file, usually the resources used internally in Tomcat. The parent loader is the Common classloader, which loads the resources configured by shared.loader in the catalina.properties configuration file. Generally, the resource WebappX that is shared by all Web applications-the parent loader is the Shared loader, the class loading / WEB-INF/classes and the jar package JasperLoader in / WEB-INF/lib/-the parent loader is the Webapp loader, loading the class files generated by the JSP compiled by the work directory application

In implementation, the above figure is not an inheritance relationship, but reflects the parent-son relationship through composition. The source class diagram of the Tomcat class loader:

Common, Catalina, and Shared are all instances of StandardClassLoader, and by default they refer to the same object. There is no difference between StandardClassLoader and URLClassLoader; WebappClassLoader is found and loaded in the following order according to the specification:

Load from the application loader path from the Bootstrap repository within JVM, that is, load from the / WEB-INF/classes directory within the Web program from the jar file in the / WEB-INF/lib within the Web program from the container Common loader repository, that is, resources shared by all Web programs

Next, take a look at the source code implementation.

3. Initialization of custom loader

The common class loader is initialized in the initClassLoaders of Bootstrap. The source code is as follows:

Private void initClassLoaders () {try {commonLoader = createClassLoader ("common", null); if (commonLoader = = null) {/ / no config file, default to this loader-we might be in a 'single' env. CommonLoader=this.getClass () .getClassLoader ();} / / specify the repository path configuration file prefix and parent loader to create a ClassLoader instance catalinaLoader = createClassLoader ("server", commonLoader); sharedLoader = createClassLoader ("shared", commonLoader);} catch (Throwable t) {log.error ("Class loader creation threw exception", t); System.exit (1);}

You can see that three class loaders have been created respectively. CreateClassLoader obtains the address of the resource repository according to the configuration, and finally returns a StandardClassLoader instance. The core code is as follows:

Private ClassLoader createClassLoader (String name, ClassLoader parent) throws Exception {String value = CatalinaProperties.getProperty (name + ".loader"); if ((value = = null) | | (value.equals (")) return parent; / / if not configured, return the incoming parent loader ArrayList repositoryLocations = new ArrayList (); ArrayList repositoryTypes = new ArrayList (); / / get the repository path String [] locations = (String []) repositoryLocations.toArray (new String [0]) Integer [] types = (Integer []) repositoryTypes.toArray (new Integer [0]); / / create a StandardClassLoader object ClassLoader classLoader = ClassLoaderFactory.createClassLoader (locations, types, parent); Return classLoader;}

After the classloader is initialized, a Catalina object is created, and eventually its load method is called to parse server.xml to initialize the container's internal components. So how does a container, such as Engine, relate to the parent loader of this setting?

The Catalina object has a parentClassLoader member variable, which is the parent loader of all components, and the default is AppClassLoader. When this object is created, it reflects the setParentClassLoader method that calls it, setting the parent loader to sharedLoader.

When the Tomcat internal top-level container Engine is initialized, Digester has a SetParentClassLoaderRule rule that associates the parentClassLoader of Catalina through the Engine.setParentClassLoader method.

4. How to break the entrustment mechanism of parents

The answer is to use Thread.getContextClassLoader (), the context loader for the current thread, which can be set dynamically while the code is running through Thread.setContextClassLoader ().

By default, the Thread context loader inherits from the parent thread, which means that the default context loader for all threads is the same as the first started thread, the main thread, whose context loader is AppClassLoader.

Tomcat first initializes a WebappClassLoader when StandardContext starts and then sets it as the context loader of the current thread, and finally encapsulates it as a Loader object, which is used when loading Servlet classes with the help of the parent-child relationship between containers.

5. Class loading for Web applications

The class loading of Web application is completed by WebappClassLoader method loadClass (String, boolean). The core code is as follows:

Preventing J2SE from being overwritten

Public synchronized Class loadClass (String name, boolean resolve) throws ClassNotFoundException {... Class clazz = null; / / (0) check whether clazz = findLoadedClass0 (name) is loaded in your internal cache; if (clazz! = null) {if (log.isDebugEnabled ()) log.debug ("Returning class from cache"); if (resolve) resolveClass (clazz); return (clazz);} / / (0.1) check whether clazz = findLoadedClass (name) is loaded in JVM's cache If (clazz! = null) {if (log.isDebugEnabled ()) log.debug ("Returning class from cache"); if (resolve) resolveClass (clazz); return (clazz);} / / (0.2) attempt to use system class loading to prevent overwriting J2SE class try {clazz = system.loadClass (name); if (clazz! = null) {if (resolve) resolveClass (clazz); return (clazz) }} catch (ClassNotFoundException e) {/ / Ignore} / / (0.5) use SecurityManager to check whether there is such access if (securityManager! = null) {int I = name.lastIndexOf ('.'); if (I > = 0) {try {securityManager.checkPackageAccess (name.substring (0Magnum I));} catch (SecurityException se) {String error = "Security Violation, attempt to use" + "Restricted Class:" + name; log.info (error, se) Throw new ClassNotFoundException (error, se);} boolean delegateLoad = delegate | | filter (name); / / (1) whether to delegate to the parent class. The default is false if (delegateLoad) {.} / / (2) try to find your own repository and load 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) {} / / (3) if the load fails at this time, delegate the load request to the parent loader if (! delegateLoad) {if (log.isDebugEnabled ()) log.debug ("Delegating to parent classloader at end:" + parent); ClassLoader loader = parent; if (loader = = null) loader = system; try {clazz = loader.loadClass (name) If (clazz! = null) {if (log.isDebugEnabled ()) log.debug ("Loading class from parent"); if (resolve) resolveClass (clazz); return (clazz);}} catch (ClassNotFoundException e) {}} / / Last load failed, throwing an exception throw new ClassNotFoundException (name) } when preventing J2SE classes from being overwritten, version Tomcat 6 uses the AppClassLoader,rt.jar core class library that is loaded by Bootstrap Classloader, but the loader is not available in Java code, and the following optimizations are made in the higher version: ClassLoader j = String.class.getClassLoader (); if (j = = null) {j = getSystemClassLoader (); while (j.getParent ()! = null) {j = j.getParent ();} this.javaseClassLoader = j

Class, version Tomcat 6, uses the AppClassLoader,rt.jar core class library that is loaded by Bootstrap Classloader, but the loader is not available in Java code, and the following optimizations are made in the higher version:

ClassLoader j = String.class.getClassLoader (); if (j = = null) {j = getSystemClassLoader (); while (j.getParent ()! = null) {j = j.getParent ();}} this.javaseClassLoader = j; is it helpful for you to read the above? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.

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: 296

*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

Servers

Wechat

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

12
Report