2

I have a problem when deploying two ear files in Jboss 7 and would be thankful for your help.

Following scenario:

EAR 1 contains EJBs which are looked up by EAR 2 (also) at server startup. Thus, EAR 1 has to be deployed before EAR 2 (via jboss-deployment-structure.xml dependency settings).

Right after being deployed, EAR 1 also needs access to classes contained in EAR 2 because of Hibernate and JNDI related class loading (among others).

But as EAR 2 isn't deployed at that time, there's a need for EAR 1 to contain a client-jar file of EAR 2.

Now, the problem is that in the course of EAR 1 and EAR 2 configuration (at server startup) ClassCastExceptions occur because...

  • (non-EJB) Java object obj1, whose class C was loaded by the classloader of EAR 1, is bound in JNDI
  • and after being looked up, supposed to be cast to object obj2 whose class C was loaded by the classloader of EAR 2

Now I wonder, if there's a possibility that these common classes of EAR 1 and EAR 2 are being loaded with the same classloader in JBoss 7. I already tried to put them in a server module, which didn't work out.

Thanks a lot for your help in advance!

PS: I'm aware of the poor design declared above. But due to restrictions, I have to follow up on it.

chris
  • 21
  • 2

1 Answers1

1

To avoid class cast exceptions, the common libraries need to be put in a classloader that is common to all applications in the two EARs, and no other copies of those libraries should exist in each application.

If it's an option to use only one EAR instead of two, put all the WARs inside a single EAR, remove the common classes from the WARs and put them on the EAR library folder.

This will associate the common classes to the EAR classloader, which is common to all the applications running inside a EAR, so that would solve the problem.

If you must use two EARS, then the common classes need to be put in a classloader at the level of the server shared by all applications.

JBoss 7 is an OSGI based container that allows to create an isolated module with a few jars and link it to an application. So if you try this:

  • create a module with the common library AND it's dependencies, see instructions here
  • link the module to all applications
  • remove the copies of those libraries from all applications and leave them only at the module

It will work fine, but don't forget to put the dependencies of the common library in the module as well otherwise it will not work, the dependencies need to be visible at the level of the module, and there can be no duplicate jars between module and applications (otherwise class cast exceptions might happen).

Another way far less recommendable but it would also work, is to put the common classes at the level of the common classloader, see this diagram. The common classloader folder is located at $CATALINA_HOME/lib (Jboss is based internally on Tomcat).

Specially if there are other applications running in that server don't try the second option. It could help to have a look at a tool I built for these type of issues, JHades.

Community
  • 1
  • 1
Angular University
  • 42,341
  • 15
  • 74
  • 81
  • Thanks a lot for your answer. It turned out that the problem causing client-jar classes contained in **EAR 1** should actually exist only in **EAR 2**, on the server side. They are supposed to be registered in a MBean server by a ServletContextListener class for configuration of **EAR 2**. The same ServletContextListener class and all of its dependent classes (which will be needed by problem causing classes of **EAR 2** later) is already loaded at **EAR 1** MBean registration. – chris Feb 07 '14 at 09:02
  • 1
    So the solution was to delete the "problem classes" from the client-jar in **EAR 1** and using another ServletContextListener and related classes in **EAR 2** for Configuration. In general, the packaging of the client-jars has to be improved in a fine-grained manner. In our use case, one EAR is not a solution because of the desired deployment of dependent EARs in different JBoss instances. And putting the configuration classes in a server module is not possible, since they depend on EJBs, which are deployed in **EAR 1**. Thanks a lot for your ideas, anyway. – chris Feb 07 '14 at 09:14