如何配置Apusic應用服務器的類裝載結構,實現jar包的類,訪問classes中的類(轉自王東明的文檔)
Apusic應用服務器目前在默認情況下是三層類裝在體系(具體介紹可參考知識庫中的相關文檔)。但是,默認情況下,因為用戶的應用部署并不是一個理想狀況,他的一個相同的類,經常部署到jar包中,同時又在classes中存在,因此三層類裝載體系下,經常出現ClassNotFound的情況。
典型的情況是:在很多的用戶代碼中,由于用戶代碼的設計考量不完善,經常出現部署在WEB-INF/lib目錄下jar中的類使用自身 ClassLoader裝載WEB-INF/classes下的類,此時容出現ClassNotFound異常,而這種情況在很多客戶應用中是相當普遍的。
但是,這種情況,在其他的應用服務器中卻很少出現異常,據此,我們有一個參數可以對Apusic應用服務器的類裝在體系進行設置,這樣,可以很大程度上避免出現ClassNotFound的問題:
ServletClassLoader本身不再持有委派ClassLoader的實例,而持有一個delegate實例。所有行為都委派給delegate去完成,delegate有三種:
????SeparatedLoaderDelegate 分jsp、WEB-INF/classes和WEB-INF/lib三個層次的類裝載體系
????IntegrateLoaderDelegate 分jsp和其他的兩個層次的類裝載體系
????SimpleLoaderDelegate 不分層次,所有類由一個ClassLoader裝載
有兩種方式可以配置delegate的類型。
????1、在web.xml中增加ContextInitParameter
????<context-param>
????????<description>
????????</description>
????????<param-name>com.apusic.web.ServletClassLoaderDelegate</param-name>
????????<param-value>
????????????com.apusic.servlet.http.IntegrateLoaderDelegate</param-value>
????</context-param>
????這樣的配置有效范圍只有當前應用
????2、通過VM參數指定 -Dcom.apusic.web.ServletClassLoaderDelegate=com.apusic.servlet.http.IntegrateLoaderDelegate
????這個配置,所有的應用都適用
????兩種都指定的情況下,以web.xml中定義的為準
????沒有任何配置,使用默認的SeparatedLoaderDelegate
注意,直到本篇文檔發稿為止(20071030),對于資源文件的處理在兩層和一層結構下,如果在jar包和classes都存在該文件的情況下,先讀到是jar包中的資源文件。對于class則是先讀到的是classes中的。
[楊威補充]:
一個錯誤的重現:在開源項目tobago中,訪問http://localhost:6888/tobago/faces/overview/toolbar.jsp時會報java.lang.ClassNotFoundException: org.apache.myfaces.tobago.example.demo.actionlistener.SimpleTabChangeListener錯誤。
錯誤原因:jar包中的TabChangeListenerTag類調用createTabChangeListener時,要訪問classes目錄下的SimpleTabChangeListener類。由于類裝載機制,部署在WEB-INF/lib目錄下jar中的類使用自身ClassLoader 裝載WEB-INF/classes下的類會出現ClassNotFound。
解決方法的補充:
Apusic4.x startapusic中添加啟動參數:
-Dcom.apusic.web.ServletClassLoaderDelegate=com.apusic.servlet.http.IntegrateLoaderDelegate
Apusic5.1 startapusic中添加啟動參數:
-Dcom.apusic.web.ServletClassLoaderDelegate=com.apusic.web.container.IntegrateLoaderDelegate