Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does classloading isolation work in jboss 5.1.x

I have a pretty standard java application which uses maven some pretty common libraries including

  • Spring
  • Hibernate ORM
  • Hibernate validator
  • Log4j

The application is composed of two war modules which share lot of common dependencies.

During development we've used both jetty and tomcat and everything is working fine. Now we're about to deploy in production and we have some constraints on this environment:

  • The application must be deployed in an already configured jboss 5.1.x instance which has a ton of libraries under both its $JBOSS_HOME/common/lib/ and $JBOSS_HOME/server//lib/, obviously there are lot of duplicates jar in these directories (especially log4j and hibernate validation stuff)
  • We can't change JBoss configuration or libraries included
  • We need to provide a single ear archive as final artifact to be deployed
  • Some application code relies on newer libraries than the provided ones

The final structure of the ear produced by maven is

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

In our pom the only two artifacts marked as provided are these, so we need them provided in the container.

<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>

However when we deploy the ear in jboss we encounter lot of classloading problems (I'll list some of them later). What we'd like to obtain is to have jboss load libraries in this order WAR->EAR->Server. In this way we can use newer libraries and safely exclude from deployment libraries shared with application server. To obtain this I created a maven jboss profile which list common libraries (log4j, slf4j, resteasy, and some other) as provided and include in the ear all the others including newer versions of jars present on the AS.

After reading lot of posts about jboss classloading isolation in JBoss 5.x the confguration I'm trying is the one contained in this article which is linked in lot of different sources and it's supposed to work.

Another attempt I've made is to deploy as two WARs to see if something changes. In that case I'm using this configuration in one of the war modules and I'm trying to deploy only that 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>

The error remain the same.

I don't know how to do, also because I can't find any official documentation about jboss-classloading.xml file with parameters explained and concrete use cases.

My question is does classloading isolation works in JBoss 5.1.x? Is it reliable? If yes how to obtain WAR->EAR->Server classloading?

Alternatively how can I completely exclude server lib and use only JARs contained in my archive? In that case do I need to include also the original provided dependencies, i.e. servlet-api, jaxb-api and maybe xml-apis?

Classloading articles I've found

  • https://access.redhat.com/site/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/JBoss_Microcontainer_User_Guide/sect-JBoss_Microcontainer_User_Guide-The_ClassLoading_Layer-ClassLoading.html
  • http://huima.wordpress.com/2011/09/16/having-fun-with-jboss-classloader-or-how-i-figured-out-how-to-get-my-application-to-work-in-jboss-5/
  • http://thoughts.inphina.com/2010/09/02/classloading-isolation-issues-with-jboss-5-1/
  • http://phytodata.wordpress.com/2010/10/21/demystifying-the-jboss5-jboss-classloading-xml-file/#comment-22

Current deployment issues

With current config the first error we encounter is this one (stack trace omitted)

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

By looking at some posts we're able to solve this by putting this in our maven jboss profile

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

After that we're getting lot of errors about instantiation of hibernate validator object which are declared as bean using this line in spring context

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

Here's the error

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)

If I remove bundled version of hibernate validator I loose some useful validators used in application code and I'm getting errors about missing annotations

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

So I'm stuck with this problem, please advise.

like image 313
Fabio Avatar asked Nov 15 '13 16:11

Fabio


1 Answers

Class loading isolation works very smoothly in Jboss 5. Refer https://community.jboss.org/wiki/ClassLoadingConfiguration?_sscc=t for more details.

like image 164
R Kaja Mohideen Avatar answered Oct 22 '22 09:10

R Kaja Mohideen