1

我有一个奇怪的问题。

我的应用程序结构简单,如下所示:一个包含 Web 模块 (WAR) 的 EAR。

我将我的特定应用程序 jar 放入 EAR 的 lib 目录中,然后将其引用到 WAR 模块的清单中。

我在 WAR 的 lib 目录中有另一个 jar,这个 jar 包含一个 servlet。

当我启动服务器并完全发布我的应用程序时,一切都很好,但是在运行时阶段,当我调用我的应用程序的入口点时,我得到一个关于这个 servlet 的 ClassNotFound 错误。(也许 servlet 使用了包含在我的应用程序 jar 中的类,该类包含在 EAR lib 中)

相反,如果我将特定的应用程序 jar 与另一个 jar(包含 servlet)一起放入 WAR 的 lib 目录中,我不会获得任何类型的错误(即使在运行时)。

但我需要将我的应用程序 jar 维护到 EAR 的 lib 目录中。

我对其他类型的 jar 没有问题,也许这种情况下的问题与 servlet 有关?类加载隔离?不知道?:(

有什么建议么?我能做些什么?

我尝试了多种关于 jboss-classloading.xml 的配置但没有成功。

PS:使用另一种类型的应用程序服务器,如 websphere,我没有任何问题,我可以将 jar 维护到 EAR lib 目录中。

假设:每个类都将使用它自己的类加载器来加载其他类。因此,如果 ClassA.class 引用 ClassB.class 那么 ClassB 需要位于 ClassA 的类加载器的类路径上,或者它的父级。

如果我将关于 jar 的类路径依赖添加到清单(WAR)到 EAR/lib 中,那么战争中的类怎么可能看不到 EAR/lib 中的类?

我快疯了......错过了另一种类型的设置?有什么安全设置吗?

堆栈跟踪:

{java.lang.NoClassDefFoundError: it/myapp/services/servlets/Dispatcher}|
at it.myapp.services.contexts.ContextManager.configureSet(ContextManager.java:2972)}
at it.myapp.services.servlets.Dispatcher.getSession(Dispatcher.java:1344)}
at it.myapp.services.servlets.Dispatcher.service(Dispatcher.java:5139)}
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)}
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)}
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)}
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)}
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)}
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)}
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145)}
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)}
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)}
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336)}
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)}
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)}
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920)}
at java.lang.Thread.run(Thread.java:722)}
Caused by: java.lang.ClassNotFoundException: it.myapp.services.servlets.Dispatcher from [Module "deployment.MyEAR.ear:main" from Service Module Loader]}
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:196)}
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:444)}
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:432)}
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:374)}
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:119)}
... 17 more}

这个问题似乎与类加载可见性有关......这很奇怪。:(

Dispatcher 是一个 servlet 类,打包在 WAR/lib 中的 jar 中,该类调用另一个类 (ContextManager),该类包含在 EAR/lib 中的 jar 中。在 WAR/lib 的清单中,我已将 jar 正确添加到 EAR/lib 中。抱歉...也许问题是相反的,即 EAR 的 jar 中的一个类似乎看不到 servlet 类进入 WAR...是否可以消除这个限制?我不想把所有的罐子都投入战争......

提前致谢。

手枪。

4

1 回答 1

0

在我们的项目中,我们有一个这样的结构(test.ear包含两个模块test.ejb.jartest.web.war):

test.ear
 +-- lib (contains 3rd party libs)
 +-- META-INF
 |    +-- application.xml (lists modules test.web.war and test.ejb.jar)
 |    +-- MANIFEST.MF
 +-- test.ejb.jar
 |    +-- META-INF
 |    |    +- ejb-jar.xml
 |    +-- com (root package of all ejb .class files)
 |         +-- ...
 +-- test.web.war
      +-- META-INF
      |    +-- MANIFEST.MF (Class-Path: test.ejb.jar)
      +-- WEB-INF
      |    +-- classes
      |    |    +-- com (root package of all war .class files)
      |    |         +-- ...
      |    +-- lib (3rd party libs only used by .war)
      |    +-- web.xml
      +-- index.html

里面的 .jar 文件的类test.ear/lib可以被test.ejb.jar和使用test.web.war

于 2013-09-26T08:02:26.627 回答