我有一个奇怪的问题。
我的应用程序结构简单,如下所示:包含 Web 模块 (WAR) 的 EAR。
我将特定的应用程序 jar 放入 EAR 的 lib 目录中,然后将其引用到 WAR 模块的 MANIFEST 中。
我在WAR的lib目录下还有另一个jar,这个jar包含一个servlet。
当我启动服务器并完全发布我的应用程序时,一切都很好,但在运行时阶段,当我调用应用程序的入口点时,我收到有关此 servlet 的 ClassNotFound 错误。 (也许 servlet 使用我的应用程序 jar 中包含的类,该类包含在 EAR lib 中)
相反,如果我将特定的应用程序 jar 与另一个 jar(包含 servlet 的 jar)一起放入 WAR 的 lib 目录中,我不会收到任何类型的错误(即使在运行时)。
但是我需要将我的应用程序 jar 维护到 EAR 的 lib 目录中。
我对其他类型的 jar 没有问题,也许本例中的问题与 servlet 有关?类加载隔离?不知道?:(
有什么建议吗?我能做什么?
我尝试了有关 jboss-classloading.xml 的多种类型的配置,但没有成功..
PS:使用另一种类型的应用程序服务器(例如 websphere)我没有任何问题,我可以将 jar 维护到 EAR lib 目录中。
假设:每个类都会使用它自己的类加载器来加载其他类。因此,如果 ClassA.class 引用 ClassB.class,则 ClassB 需要位于 ClassA 的类加载器或其父类的类路径上。
如果我将有关 jar 的类路径依赖项添加到 WAR/lib 的 list 中,那么 war 中的类怎么可能看不到 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 是一个打包在 WAR/lib 中的 jar 中的 servlet 类,该类调用包含在 EAR/lib 中的 jar 中的另一个类 (ContextManager)。 在 WAR/lib 的 list 中,我已将 jar 正确添加到 EAR/lib 的类路径中。 抱歉...也许问题是相反的,即 EAR 的 jar 中的类似乎无法看到 WAR 中的 servlet 类...是否可以消除此限制?我不想把所有的 jar 都投入 war ......
提前致谢。
IlPistolero。
最佳答案
在我们的项目中,我们有这样的结构( test.ear
包含两个模块 test.ejb.jar
和 test.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
test.ear/lib
内.jar文件的类可由 test.ejb.jar
使用和test.web.war
.
关于java - EAP 6.1 中的类加载问题 - JBoss 7.2/WAR 类看不到 EAR 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19022178/