EAP 6.1中的类加载问题 - JBoss 7.2 / WAR类没有看到EAR类

时间:2013-09-26 07:40:37

标签: java classloader manifest jboss-eap-6

我有一个奇怪的问题。

我的应用程序结构简单:包含Web模块(WAR)的EAR。

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

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

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

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

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

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

有什么建议吗?我该怎么办?

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

PS:对于像websphere这样的其他类型的应用服务器,我没有任何问题,我可以将jar维护到EAR lib目录。

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

如果我将清单(WAR)添加到关于jar的类路径依赖关系到EAR / lib中,那么进入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是一个servlet类,在jar中打包到WAR / lib中,这个类调用另一个类(ContextManager),它包含在EAR / lib的jar中。 在WAR / lib的清单中,我已经正确地将jar路径添加到EAR / lib中。 对不起......也许问题是相反的,即EAR的jar中的一个类似乎看不到servlet类进入WAR ...有可能删除这个限制吗?我不想把所有的罐子都投入战争......

提前致谢。

IlPistolero。

1 个答案:

答案 0 :(得分: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

test.ear/lib内的.jar文件的类可以由test.ejb.jartest.web.war使用。