java - 从 lib 文件夹中的类扩展 WAR 中的抽象类

标签 java tomcat web-applications servlets classloader

我想启用以下场景:

  • 我的 web 应用程序(WAR 文件)是自己部署在 Tomcat 上的

  • 我的 Web 应用程序以 IFace 接口(interface)和 AbstractIFace 抽象基础实现的形式为扩展提供 API,其类文件部署在 WAR 文件中

  • 应用程序的扩展作为 JAR 文件交付,放置在类路径中的某个位置(即 WAR 外部)

我编译了一个 ConcreteIFace 类,它扩展了 AbstractIFace 并将其打包到一个 JAR 中。我将 JAR 放在 $TOMCAT_HOME/lib 中,并将 WAR 部署在 webapps 中。当我尝试从 WAR 中的 servlet 执行以下操作时:

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,则会显示类似的堆栈跟踪

我的问题是:

  • 因为所有必需的类都在应用程序类路径中,为什么我有 NoClassDefFound

  • 是否有可能实现我一开始提出的场景?如果是,怎么办?

最佳答案

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

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

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

其他选项包括进入企业文件,这可能具有相互依赖性,或者将网络服务器嵌入到应用程序中(而不是相反)。

关于java - 从 lib 文件夹中的类扩展 WAR 中的抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11518984/

相关文章:

java - android 中 RxJava2 中的 subscribe() 和 subscribeWith() 有什么区别?

java - 使用 Spring 框架在 JSP 页面中显示可变长度的字符串列表

web-applications - 说明 Web 应用程序软件架构(使用 Angular)的最佳方式是什么?

java - OC4J 问题与 ssl (secure-web-site.xml)

java - 通过从命令行安装 tomcat 7 maven 插件来下载 spring petclinic

api - 获取最高分辨率图标

java - 使用 java 或 xslt 根据 xml 的内容拆分 xml

java - 抛出异常问题

java - 检查字符串中的大写字母并找到位置

Tomcat 服务器状态页面不显示所有详细信息