Java 从lib文件夹中的类扩展WAR中的抽象类
我想启用以下场景:Java 从lib文件夹中的类扩展WAR中的抽象类,java,tomcat,web-applications,servlets,classloader,Java,Tomcat,Web Applications,Servlets,Classloader,我想启用以下场景: 我的web应用程序(WAR文件)单独部署在Tomcat上 我的web应用程序以IFace接口和AbstractIFace抽象基实现的形式为扩展提供API,其类文件部署在WAR文件中 应用程序的扩展以JAR文件的形式交付,放置在类路径的某个位置(即WAR外部) 我编译了一个concretiface类,该类扩展了AbstractIFace,并将其打包到一个JAR中。我将JAR放在$TOMCAT_HOME/lib中,并在webapps中部署了WAR。当我在战争中从servlet
- 我的web应用程序(WAR文件)单独部署在Tomcat上
- 我的web应用程序以
接口和IFace
抽象基实现的形式为扩展提供API,其类文件部署在WAR文件中AbstractIFace
- 应用程序的扩展以JAR文件的形式交付,放置在类路径的某个位置(即WAR外部)
concretiface
类,该类扩展了AbstractIFace
,并将其打包到一个JAR中。我将JAR放在$TOMCAT_HOME/lib
中,并在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服务器嵌入到应用程序中(与其他方式相反)。您的API类位于WAR中,并且$TOMCAT_HOME/lib中的类无法访问。
一个建议是将您的API-a IFace和AbstractIFaceClass分开,以分开jar,并将其放置在$TOMCAT_HOME/lib中。如果您能够清晰地将这些部分分开,那么这是可行的。但是,如果AbstractIFaceClass依赖于web应用程序中的许多其他内容(您也必须移动所有这些可传递的依赖项),则不会很好地工作。如果您不能分离这些内容,则说明您的设计很糟糕。我理解这一点,谢谢。但很明显,应用程序可以访问容器类,而问题恰恰相反:查看错误,它是关于
AbstractIFace
,意思是ConcreteIFace
确实被找到并正在加载。是吗?是的,应用程序可以看到(一些)容器类,但不能看到其他的容器类。ConcreteIFace是容器的一部分(现在您已将其移动到lib),因此它无法看到其父类(它是应用程序的一部分)。当你编译它的时候,你也必须让它访问应用程序中的类,对吗?如果你想使用TOMCAT_HOME/lib,你必须像@Slavus建议的那样,把所有的东西分解成一个jar文件。