一尘不染

Tomcat Classloader的顺序:通用,共享和服务器

tomcat

Tomcat 类加载器HOW-TO文档描述了4种不同的类加载器:

  1. 引导程序
  2. 系统
  3. 共同
  4. 网络应用

但是,在默认的catalina.properties文件中,还为共享和服务器类加载器定义了属性。在文件的默认版本中,这两个属性均为空,并且注释说:

如果保留为空白,则“通用”加载程序将用作Catalina的“共享” /“服务器”加载程序。

我找不到有关这些类加载器的任何其他文档。我的问题是,相对于通用加载器,按哪个顺序搜索共享加载器和系统加载器?另外,这些类加载器的预期用途是什么?


阅读 330

收藏
2020-06-16

共1个答案

一尘不染

我最近也遇到了这个问题,这是我发现的(全部来自Tomcat 7主干)

如果保留为空白,则“通用”加载程序将用作Catalina的“共享” /“服务器”加载程序。

这是相关的资料

89      private void initClassLoaders() {
90          try {
91              commonLoader = createClassLoader("common", null);
92              if( commonLoader == null ) {
93                  // no config file, default to this loader - we might be in a 'single' env.
94                  commonLoader=this.getClass().getClassLoader();
95              }
96              catalinaLoader = createClassLoader("server", commonLoader);
97              sharedLoader = createClassLoader("shared", commonLoader);
98          } catch (Throwable t) {
99              handleThrowable(t);
100             log.error("Class loader creation threw exception", t);
101             System.exit(1);
102         }
103     }

106     private ClassLoader createClassLoader(String name, ClassLoader parent)
107         throws Exception {
108 
109         String value = CatalinaProperties.getProperty(name + ".loader");
110         if ((value == null) || (value.equals("")))
111             return parent;

因此,如果未定义任何内容,它们将退回到使用common.loader条目。


至于它们的加载顺序,这里是从源代码加载它们的

229         Thread.currentThread().setContextClassLoader(catalinaLoader);
230 
231         SecurityClassLoad.securityClassLoad(catalinaLoader);
232 
233         // Load our startup class and call its process() method
234         if (log.isDebugEnabled())
235             log.debug("Loading startup class");
236         Class<?> startupClass =
237             catalinaLoader.loadClass
238             ("org.apache.catalina.startup.Catalina");
239         Object startupInstance = startupClass.newInstance();
240 
241         // Set the shared extensions class loader
242         if (log.isDebugEnabled())
243             log.debug("Setting startup class properties");
244         String methodName = "setParentClassLoader";
245         Class<?> paramTypes[] = new Class[1];
246         paramTypes[0] = Class.forName("java.lang.ClassLoader");
247         Object paramValues[] = new Object[1];
248         paramValues[0] = sharedLoader;
249         Method method =
250             startupInstance.getClass().getMethod(methodName, paramTypes);
251         method.invoke(startupInstance, paramValues);

第229行设置common.loader classLoader,然后第251行设置shared.loader
classloader设置为Catalinas父类加载器。

2020-06-16