2011-06-06 159 views
16

Tomcat的Class Loader HOW-TO文檔描述4個不同的類加載器:順序:普通,共享和服務器

  1. 引導
  2. 系統
  3. 的webapp
  4. 普通

在但是,默認的catalina.properties文件也有爲共享和服務器類加載器定義的屬性。在該文件的默認版本的這兩個屬性是空的,評論說:

如果留爲空白,「常用」裝載機 將用作Catalina的 「共享」 /「服務器」裝載機。

我一直沒能找到關於這些類加載器的任何其他文檔。我的問題是,共享加載程序和系統加載程序按照什麼順序搜索?另外,這些類裝載機的預期用途是什麼?

+0

另請參見http://stackoverflow.com/questions/5474765/order-of-loading-jar-files-from-lib-directory – rogerdpack 2014-09-26 17:50:30

回答

9

我最近就遇到了這個問題,也是在這裏是我發現,(這是所有從Tomcat 7主幹)

首先,If left as blank, the "common" loader will be used as Catalina's "shared"/"server" loader.

下面是相關source

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條目。


至於它們在加載順序, 這裏是在加載它們的來源,從source

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類加載器,然後行251套shared.loader classloader被設置爲Catalinas父類加載器。

1

奇怪,Tomcat 5.5 classloader doc仍然有shared加載程序記錄,但6.0 doesn't;沒有你引用的v7.0。也許他們會貶低它?

我們確實使用共享加載器廣泛地覆蓋我們的軟件的香草版本隨附的現有類。我們製作的軟件來自發行版,並且爲一個客戶製作完整的新版本(這需要一個關鍵的bug修復)太昂貴了(重新測試一切,重建,提供新文檔,新版本號等等)。因此,我們所做的是提供一個「修補程序」,它將進入共享加載程序並覆蓋webapp中的相關.class

大多數情況下,「hotfix」只是一個類,所以整體迴歸風險很小。

當我們的軟件升級時,升級會刪除「修補程序」,因爲更正後的代碼也會出現在我們軟件的下一個版本中。

我也可以想象其他人使用共享類加載器來產生跨越許多不同webapps的東西。

+1

所以,@ mindas,你說共享類加載器實際上是之前搜索webapp類加載器?這看起來不正確。 – 2011-06-06 23:34:11

1

同意mindas,apache tomcat組可能會考慮取消服務器&共享類加載器。關於webappclassloader和standardclassloader(通用類加載器)的順序,Jianbo有一個有趣的帖子。他做了一個簡單的測試來證明它。 http://web.archive.org/web/20120303091507/http://www.jianbozhu.net/2012/02/14/tomcat-classloader-demonstration/

它的基本要點是在tomcat中,類加載器首先從webapp加載類,然後共享/通用,然後是系統。