类加载隔离是否适用于jboss 5.1.x.

时间:2013-11-15 16:39:51

标签: java hibernate maven jboss classloader

我有一个非常标准的java应用程序,它使用maven一些非常常见的库,包括

  • 弹簧
  • Hibernate ORM
  • Hibernate验证器
  • 的Log4j

该应用程序由两个共享许多共同依赖项的war模块组成。

在开发过程中,我们使用了jetty和tomcat,一切正常。现在我们即将部署在生产环境中,我们对这种环境有一些限制:

  • 应用程序必须部署在已配置的jboss 5.1.x实例中,该实例在$ JBOSS_HOME / common / lib /和$ JBOSS_HOME / server // lib /下都有大量库,显然有很多重复的jar在这些目录中(特别是log4j和hibernate验证的东西)
  • 我们无法更改JBoss配置或包含的库
  • 我们需要提供单个ear存档作为要部署的最终工件
  • 某些应用程序代码依赖于比提供的库更新的库

maven生产的耳朵的最终结构是

application.ear
├── META-INF
│   ├── application.xml
│   └── jboss-classloading.xml
├── lib
│   ├── long list of shared jars
│   ├── ...
│   ├── // some of key libraries which also are in AS lib folder
│   ├── hibernate-validator-4.3.1.Final.jar
│   ├── jaxb-impl-2.1.10.jar
│   ├── log4j-1.2.17.jar
│   ├── slf4j-api-1.5.5.jar
│   ├── slf4j-log4j12-1.5.5.jar
│   └── validation-api-1.0.0.GA.jar
├── webapp1.war
└── webapp2.war

在我们的pom中,标记为提供的唯一两个工件是这些,因此我们需要在容器中提供它们。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>${servlet.version}</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>${jaxb.version}</version>
    <scope>provided</scope>
</dependency>

然而,当我们在jboss中部署耳朵时,我们会遇到很多类加载问题(我稍后会列出其中一些)。我们想要获得的是按顺序使用jboss加载库WAR-&gt; EAR-&gt; Server。通过这种方式,我们可以使用更新的库并安全地从与应用程序服务器共享的部署库中排除。为了获得这个,我创建了一个maven jboss配置文件,列出了所提供的公共库(log4j,slf4j,resteasy和其他一些),并将所有其他库包括在AS中包含更新版本的罐子。

在JBoss 5.x中阅读了很多关于jboss类加载隔离的帖子后,我正在尝试的配置是this article中包含的配置,它在许多不同的源中链接,它应该可以工作。

我做的另一个尝试是部署为两个WAR来查看是否有变化。在那种情况下,我在其中一个战争模块中使用此配置,而我正在尝试仅部署该战争

<classloading xmlns="urn:jboss:classloading:1.0"
              domain="myapp.war"
              parent-domain="DefaultDomain"
              parent-first="false"
              export-all="NON_EMPTY"
              top-level-classloader="true"
              import-all="true">
</classloading>

错误保持不变。

我不知道该怎么做,也因为我找不到任何关于jboss-classloading.xml文件的官方文档,其中包含参数说明和具体用例。

我的问题是类加载隔离是否适用于JBoss 5.1.x?它可靠吗?如果是,如何获取WAR->EAR->Server类加载?

或者,如何完全排除服务器lib并仅使用存档中包含的JAR?在这种情况下,我是否还需要包含原始提供的依赖项,即servlet-api,jaxb-api和xml-apis?

我发现的类加载文章

当前部署问题

使用当前配置,我们遇到的第一个错误就是这个(忽略堆栈跟踪)

13:10:11,972 INFO  [STDOUT] 13:10:11,969 ERROR [ContextLoader] Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory

通过查看some posts,我们可以通过将其添加到我们的maven jboss配置文件来解决此问题

<dependency>
    <groupId>xml-apis</groupId>
    <artifactId>xml-apis</artifactId>
    <version>1.0.b2</version>
    <scope>provided</scope>
</dependency>

之后我们在hibernate验证器对象的实例化方面遇到了很多错误,这些错误在spring上下文中使用这一行声明为bean

<!-- Hibernate validator stuff -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

这是错误

16:52:58,430 ERROR [ContextLoader] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validator' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.jboss.logmanager.LogContext.getAttachment(Ljava/lang/String;Lorg/jboss/logmanager/Logger$AttachmentKey;)Ljava/lang/Object;
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)

如果我删除捆绑版本的hibernate验证器,我会松开一些在应用程序代码中使用的有用验证器,并且我收到有关缺少注释的错误

java.lang.NoClassDefFoundError: [Ljavax/validation/constraints/Pattern$Flag;

所以我坚持这个问题,请指教。

1 个答案:

答案 0 :(得分:2)

类加载隔离在Jboss 5中运行非常顺利。有关详细信息,请参阅https://community.jboss.org/wiki/ClassLoadingConfiguration?_sscc=t