How to deploy two cross-dependent EARs in JBoss 7 in order to prevent ClassCastExceptions? - deployment

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.

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.

Related

JBoss eap 6 (as 7) - 2 different classes with same package and name

I am having an issue with a 3rd party developer.
They have provided a number of jars, and unfortunately in 2 different jars they have different implementations of a class (same name, same package).
We deploy using a single war file where both jars (among many others) are packaged together in web-inf/lib directory and unfortunately both jars are needed.
Is there a way where I can guarantee in JBoss eap 6 that the class from a.jar gets loaded before the class from b.jar?
Thanks.
All of your answers about classloading on JBoss can be found here at this link. But since now I advise you to read the "JBoss Deployment Structure File" section
With the "jboss-deployment-structure.xml" JBoss specific deployment descriptor you can control class loading in a fine grained manner. It should be placed in the top level deployment, in META-INF (or WEB-INF for web deployments). It can do the following:
Prevent automatic dependencies from being added
Add additional dependencies
Define additional modules
Change an EAR deployments isolated class loading behaviour
Add additional resource roots to a module

JBoss EAR with multiple WARs and shared dependencies including a common datasource file

We are going from a single WAR to multiple WARs to be repackaged within an EAR file in JBoss. I would like to be able to do the following:
Move common libraries to under the root of the new EAR so that they don't have to be duplicated within each of the WARs (I suppose under $EAR_ROOT/lib?).
Move the *-ds.xml file from under $JBOSS_HOME/server//deploy to under the EAR so that the datasource is scoped to the application (at least from a packaging standpoint - I realize there is no preventing a JNDI lookup from other WAR, that's okay).
Repackage the Hibernate DAOs and dependencies to a new to-be-shared JAR file and put them in the common location as well (to be shared by both the WARs).
I have some sense on what needs to happen but could use some help so that I don't have to create all of this structure and the related Ant/Maven targets/goals from scratch. For instance, should the datasource file be referenced in jboss-app.xml or in application.xml directly?
There seem to be multiple ways of skinning this cat and I am looking for a nice, clean example to do this (in the interest of not having to reinvent the wheel).
Use JBoss Developer Studio, it does all that for you

EJBs 2.0 on OpenEJB - Where do I put the needed jars?

We've been using WAS 6.1 so far to deploy our web apps. Now we need to migrate to an economics-savvy Tomcat + OpenEJB solution. The OpenEJB 3.1.2 container is plugged into Tomcat 6.18, no standalone OpenEJB server here.
So here I am, trying to deploy my EJB 2.1 objects into OpenEJB...
My problem is that the EJBs code requires external .jar libraries, and I don't know where to put them so that they are actually taken into account into the container's classpath. It works fine into catalina.home/lib, so it does into openejb.home/lib. But still I'd rather find out a way to package the EJBs so that they are easy deployed with their linked .jar dropped right into place to be used by the OpenEJB container.
It can include building up an .ear or a .jar with the right descriptor files... Any solution that works is good enough for me.
Can possibly anyone help?
Ear Approach
You can just drop it into the Tomcat webapps/ directory and it will be picked up.
Example ear (valid):
myapplication.ear
lib/
lib/libraryOne.jar
lib/libraryTwo.jar
redEjbs.jar
blueEjbs.jar
Common mistake (invalid):
myapplication.ear
libraryOne.jar (err. not a javaee module)
libraryTwo.jar (err. not a javaee module)
redEjbs.jar
blueEjbs.jar
Only Java EE modules are allowed at the root. These are EJB jars, .war files, Connector .rar files and Application Client jars. Prior to Java EE 5, libraries had to be explicitly listed in an application.xml file. Java EE 5 and forward they can be added to a lib/ directory and be understood to be just plain jars as opposed to a Java EE module.
Collapsed EAR approach
In OpenEJB/Tomcat you can put all your libraries into the war file and be free of the ear concept. This is now part of Java EE 6.
mywebapp.war
WEB-INF/lib/libraryOne.jar
WEB-INF/lib/libraryTwo.jar
WEB-INF/lib/redEjbs.jar
WEB-INF/lib/blueEjbs.jar
Common mistake, including specs:
mywebapp.war
WEB-INF/lib/javax.ejb.jar (err. clashes with the related system library)
WEB-INF/lib/libraryOne.jar
WEB-INF/lib/libraryTwo.jar
WEB-INF/lib/redEjbs.jar
WEB-INF/lib/blueEjbs.jar
Doesn't sound like that is the issue, but adding for completeness.
Common mistake, broken dependencies:
tomcat/lib/libraryTwo.jar
mywebapp.war
WEB-INF/lib/libraryOne.jar
WEB-INF/lib/redEjbs.jar
WEB-INF/lib/blueEjbs.jar
The above is not invalid from a spec perspective and is impossible for the server to detect, but still can lead to apps not loading correctly. If libraryTwo.jar needs classes in libraryOne.jar then this app will never work as the Tomcat "lib" classloader cannot see classes from the "webapp" classloader, so classes from libraryTwo.jar will never successfully load. Unfortunately, the vm will almost never say the actual class that was missing and instead will report the first class in the chain of events that lead to needing a class that was missing. This is almost always a bean or servlet class.
Thanks David.
I tried all of the above, but still no luck.
The Collapsed EAR approach wouldn't work for me I guess, as I far as I know Tomcat 6.0.18 doesn't comply to the J2EE 6 specs. Maybe I'm wrong , but I tried and it didn't work anyway. So back to the standard EAR approach.
My EAR is organized exactly as described in your very first example. One Ejb jar, two library jars in /lib, and that's it. Tomcat still can't instanciate my EJB because the EJB class relates to an unreachable class from Library Jar Two.
I simplified my application.xml file so that it only declares one single EJB:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ...>
<application>
<display-name>ProxyaEAR</display-name>
<module id="EjbModule">
<ejb>ProxyaEJB.jar</ejb>
</module>
</application>
Any other thoughts??

Deploying multiple versions of same EJBs and classes to same JBoss server

I have a few separate application projects (EARs) with multiple EJBs that I want to deploy to the same JBoss server. Now, some of the projects may have the same EJBs, but different versions. In similar circumstances, some projects may use different versions of the same "ordinary" classes (i.e. classes loaded within VM, without JNDI lookup).
With OC4J, this seems not to have been a problem, but now with JBoss, I get the impression that everything resides in the same "name space" (or class loader perhaps). Am I correct in this assumption?
Basically, what I want to do (or ensure) are two things:
From a client that does a JNDI-lookup of an EJB, I want to be able to indicate which application it resides in, so that the correct version of the EJB is returned.
From within an EJB, when instantiating a class, I want to ensure that the class is the one deployed with the same application (EAR) as the EJB was.
I think I read that you could configure some "isolation" properties for EJBs, am I guessing correctly in that might would solve my second point?
JBoss's default behaviour is to use a flat classloader. This reduces the footprint, but as you've found, it makes deploying multiple applications troublesome.
Thankfully, the fix is easy. In the ear-deployer.xml file in the deploy directory, make sure the following parameter is set:
<attribute name="Isolated">true</attribute>
This will give each deployed EAR its own classloader space. It will still be able to access stuff from the JBoss lib directory, but the deployed EARs will be invisible to each other.
You're correct that classes from different EAR's reside in the same "space". JBoss uses by default a flat classloader hierarchy, meaning that all classes (except for WAR packaged ones) are loaded by the same classloader. With the introduction of JBoss 5 there's a new standard profile that strictly follows the Java EE rules and thus supports isolated classloading. Older JBoss versions also support this behavior through the callByValue and isolate properties in the deployer configuraion.

How to structure a Java EE system? How is the term application and thus the content of an EAR defined?

I am in the process of designing a build system and the directory structure for a large software system developed with Java EE 5. The build system will be implemented using ant.
We have multiple different services, which are grouped thematically. Each service offers either a web service or EJBs. Each service runs on a dedicated application server cluster. Thus, we have multiple clusters and some of these clusters can be grouped logically by topics.
I did read generic definitions and examples, but I am still confused about the Java EE terminology:
What is a Java EE application? And thus, what is the content of an EAR file?
What is a Java EE Project? (the term is used by Netbeans as well as in the Java Blueprints Guidelines Project Conventions for Enterprise Applications)
Do I have to put all EJB and WAR-module-package-files into one single EAR, so that this single EAR contains our complete system?
Or do I put each group of services into one EAR, despite the fact that these services are only grouped logically but not technically?
Or do I assemble a separate EAR for each service, i.e. most often only containing a single EJB jar file and sometimes and EJB and a WAR file?
Or do I dismiss the concept of applications and merely build EJB and WAR files, so that I have exactly one deployment file for each application server cluster?
I guess, my main question is: What are the advantages of packaging EAR files?
As I see it at the moment, there is only the need for EAR-EJB and WAR files and additionally the concept of nested subproject in the ant-build-system and the directory structure of our source?
Edit: Thanks a lot for the answers! It seems to me that an application packaged into an ear is a rather atomic subsystem. So I guess, that I will have a nested subproject-structure (only logical, visible only to the build system and in the directory structure of the source) and a rather large amount of EARs, each of those containing mostly only one ejb-jar and/or war module and implementing a single service (which is deployed on a single application server cluster).
I think what you decide to put in each EAR is governed by organizational and technical issues.
I think most important technical role of an EAR is a classloader root in a runtime environment. This normally means you can deploy different versions of libraries and your own classes in different EAR's. This means you should keep your container root classpath fairly empty (or as supplied by the container vendor), because it may allow one phsyical container to service multiple applications using possibly conflicting libraries. This is great news if you're developing a number of different applications using a common code-base. You can have a number of projects deploying to the same farm of servers without messing up for eachother.
You will normally never deploy a smaller unit of software than the EAR. Each EAR can be more or less fully self-contained. I would normally let the content of these refelect what the owning organization thinks of as applications or subsystems. You can usually package the same components in multiple EAR's.
Lots of questions here.
Java EE projects are either EAR or WAR deployments that use Java EE technology. If you have a WAR with JSPs and JDBC access of a relational database, that's a Java EE project. The original intent was that EAR files were "enterprise", and that meant EJBs. An EAR file an contain EJBs, WARs, JARs, the whole enchilada.
Thinking in terms of services are a little different. I think deployment deserves careful consideration, because components that are packaged together must be brought down and up together if any maintenance has to be done.
So think carefully about how you package your services. It's not an all or none blanket answer, IMO. You should look at what your services are doing and how they might be used together to decide how they should be packaged and deployed.
Both Logical and Organizational considerations come into play. Each EAR would contain all the pieces that are related for a particular capability. We can always assume that each EAR will be self contained and can be deployed on one or more containers. The typical approach that I have always followed is to have each EAR contain one or more jars and wars. Each war or jar contains some key component or set of related components. The EAR represents an Enterprise application that contains the components and web apps for the application.
An Example is a Payment processing system I was involved in.
The EAR contained everything required to run the Payment Processing system. This included half a dozen jars and 3 wars. Each jar represented some functionality or logical grouping of functionality. Each war represented a web app.
An example of the jar's composition:
a jar for core functionality
a jar for ejbs
a jar for our advanced financial math pieces
a jar for our security pieces
etc.
Having multiple jars was dictated by the fact that different people developed different pieces so they worked in different Eclipse projects and combined them all as needed.
There are no hard and fast rules, just whatever works for your team and situation.