2012-07-17 18 views
0

我想啓用以下情形:lib文件夾中擴展在戰爭時期的抽象類與類

  • 我的web應用程序(WAR文件)部署在Tomcat自身

  • 我的web應用程序提供了一個API,用於擴展在IFace接口的形式和AbstractIFace抽象的基本實現,它的類文件在WAR文件中部署

  • 擴展的應用程序作爲JAR文件提供以放置在類路徑中的某個位置(即,外部WAR)

我編譯一個ConcreteIFace類延伸AbstractIFace並將其打包成JAR。我把JAR放入$TOMCAT_HOME/lib,並將WAR部署在webapps

Class clazz = Class.forName("ConcreteIFace"); 

我碰到下面的堆棧跟蹤:

java.lang.NoClassDefFoundError: AbstractIFace 
    java.lang.ClassLoader.defineClass1(Native Method) 
    java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) 
    java.lang.ClassLoader.defineClass(ClassLoader.java:615) 
    java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) 
    java.net.URLClassLoader.defineClass(URLClassLoader.java:283) 
    java.net.URLClassLoader.access$000(URLClassLoader.java:58) 
    java.net.URLClassLoader$1.run(URLClassLoader.java:197) 
    java.security.AccessController.doPrivileged(Native Method) 
    java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
    java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
    java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    java.lang.Class.forName0(Native Method) 
    java.lang.Class.forName(Class.java:247) 
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1698) 
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556) 
    java.lang.Class.forName0(Native Method) 
    java.lang.Class.forName(Class.java:169) 
    com.backbase.sample.DummyServlet.service(DummyServlet.java:14) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 

類似的堆棧跟蹤,提出如果ConcreteIFace直接實現IFace,而不是通過AbstractIFace

要去當我嘗試從WAR一個servlet以下

我的問題是:

  • ,因爲所有必需的類都在應用程序類路徑中,爲什麼我有NoClassDefFound

  • 甚至有可能實現我在開始介紹的場景嗎?如果是這樣,怎麼樣?

回答

2

在Web應用程序中,類路徑是分開的。 Web應用程序無法查看對方的類,Tomcat無法看到應用程序的類,應用程序無法看到Tomcat的內部類(僅顯示類似於Servlet API的公開接口)。

Web應用程序應該是獨立的,並獨立於容器。

最簡單的方法是重新打包war文件以包含插件。

其他選項包括可能存在相互依賴性的企業檔案,或將Web服務器嵌入到應用程序中(而不是其他方式)。

+0

我明白這一點,謝謝。但顯然,應用程序*可以*訪問容器類,而相反的問題則在於:查看與「AbstractIFace」有關的錯誤,這意味着'ConcreteIFace'確實被發現並正在被加載。對? – skuro 2012-07-17 09:29:14

+0

是的,應用程序可以看到(某些)容器類,但不是相反。 ConcreteFace是容器的一部分(現在你把它移動到了lib中),所以它不能看到它的父類(它是應用程序的一部分)。當你編譯它時,你必須讓它訪問應用程序中的類,對吧?如果你想使用TOMCAT_HOME/lib,你必須把所有這些東西分解成一個jar文件,就像@Slavus所說的那樣。 – Thilo 2012-07-17 10:07:09

0

您的API類位於WAR中,不能被$ TOMCAT_HOME/lib中的類訪問。 一個建議是將您的API -Face和AbstractIFaceClass分離到單獨的jar並將其放置$ TOMCAT_HOME/lib。

+1

可行,如果你可以把這些碎片乾淨地分開。但是,如果AbstractIFaceClass依賴於Web應用程序中的許多其他內容(即,您還必須移動所有這些傳遞依賴關係),那麼效果並不理想。 – Thilo 2012-07-17 09:00:21

+0

如果你不能分開這個東西,你有不好的設計。 – Slavus 2012-07-17 09:10:30