0

I want to enable the following scenario:

  • my web application (WAR file) is deployed on Tomcat on its own

  • my web application provides an API for extensions in the form of an IFace interface and AbstractIFace abstract base implementation, whose class files are deployed within the WAR file

  • extensions to the applications are delivered as JAR files to be placed somewhere in the classpath (i.e. external to the WAR)

I compiled a ConcreteIFace class which extends AbstractIFace and packaged it into a JAR. I put the JAR in $TOMCAT_HOME/lib and deployed the WAR in webapps. When I try the following from a servlet in the WAR:

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

I get the following stack trace:

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)

A similar stack trace is presented if ConcreteIFace directly implements IFace instead of going through AbstractIFace

My questions are:

  • as all the required classes are in the application classpath, why do I have NoClassDefFound?

  • is it even possible to achieve the scenario I presented at the beginning? If so, how?

4

2 回答 2

2

在 Web 应用程序中,类路径是隔离的。Web 应用程序看不到彼此的类,Tomcat 看不到应用程序的类,应用程序看不到 Tomcat 的内部类(只有暴露的接口,如 Servlet API)。

Web 应用程序应该是自包含的,并且独立于容器的。

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

其他选项包括进入企业档案,它可以具有相互依赖性,或者将 Web 服务器嵌入应用程序中(而不是相反)。

于 2012-07-17T08:53:06.943 回答
0

您的 API 类位于 WAR 中,并且不能被 $TOMCAT_HOME/lib 中的类访问。一个建议是将您的 API-a IFace 和 AbstractIFaceClass 分开以分开 jar 并将其放置在 $TOMCAT_HOME/lib 中。

于 2012-07-17T08:57:59.943 回答