I have a (very) old application written with several Message Driven Beans (don't worry, I will eventually chainsaw them out and write something maintainable into the future).
The application is packaged as an EAR with multiple JARs inside. Here's a simplified layout:
- app
-- appDataModel
-- appJaxbModel
-- appEjb
-- appEar
My problem arises due to the fact that the EAR works fine with Weblogic 10.3.x, but classes in the appEjb module (built as appEjb.jar inside the EAR) cannot see a class in the appDataModel (built as appDataModel.jar inside the EAR) when I deploy to JBoss 6.4 EAP. I've also run Red Hat's migration tool, but nothing was suggested (related to this anyways)
I've tried setting the isolation in jboss-deployement-structure.xml to false, with no luck. This could be something simple, or it could be something related to difference in classloading: I really have no idea.
Is there anyone out there who can help?
If appDataModel and appJaxbModel are not ejb-jars then move them to a lib directory inside the EAR. They will then be visible to everything.
You should finish up with a structure like:
- app
-- lib
-- appDataModel
-- appJaxbModel
-- appEjb
-- appWar
This is completely portable and should also work in WebLogic 10.3.x
(I'm assuming that your last module was intended to be a WAR, as you cannot package an EAR within an EAR).
Related
I have created and deployed one war for my application.
I wanted to use derby for integration testing so I created one module in Jboss.
At run time I am getting ClassCastException for same class, since the class is getting loaded twice: first from war, then from my module's jar.
To elaborate, my war, say application.war contains myderby.jar and under my module i have added myderby.jar .My class, say Custom.java, is present in myderby.jar.
If you want a jar to be accessible to multiple WARs, JARs, or an EAR and a WAR/JAR - or in fact any such combination, you can include it as a global module. Here's how it can be done.
This might also help.
As Suggested I followed the following link
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Administration_and_Configuration_Guide/Add_a_module_to_all_deployments.html and it worked for me.
Hullo - issue is this:
I wrote a servlet in Eclipse which requires mysql-connector-java-5.1.22-bin.jar
To compile I need to add the jar via the project's "Java Build Path"
To deploy I need to add the jar to the project's "Deployment Assembly"
To run the servlet within eclipse I need to add the jar to the servlet's Run Configuration -> Classpath
It's not the end of the world re-re-repeating myself like this, but it does seem odd.
Given that Eclipse gets a lot of other stuff correct I'm guessing / hoping that maybe I'm overlooking some feature to avoid this silliness (I cannot imagine a scenario where you'd benefit from entering this in 3 different spots ... but maybe I'm being uncreative here ...).
Insights appreciated :-)
The only thing you need to do is to drop the jar in WebContent/WEB-INF/lib.
You are developing a Java Web project, so the traditional place to put the required libs (JAR files etc) is under /WEB-INF/lib. And you do it only once.
In Eclipse, when you create Dynamic Web Project the appropriate project structure is generated for you (this is a development structure). In this case you place your JAR files in ProjectName/WebContent/WEB-INF/lib folder. And this folder is *automatically included in the project's build path.
Considering the fact that it is a Java Web project (you said you use servlets) you have to deploy your web app to some Application Server, like GlassFish, JBoss, WebLogic, WebSphere etc, or more simple Web Container like Apache Tomcat. If you do this thru Eclipse, then again your web project is automatically deployed.
NB!
There may be some additional details related to using libraries.
For instance, when it comes to using database drivers (MySql, PostgreSQL, Oracle etc) Tomcat advises the following while configuring JNDI Datasource (quote):
Before you proceed, don't forget to copy the JDBC Driver's jar into
$CATALINA_HOME/lib
In your case (MySQL) see the example here: MySQL DBCP Example
Also see my answer related to Webapp configuration file organization convention.
Hope this will help you.
P.S. Here is a step-by-step example: How do I access MySQL from a web application?
I'm having a strange problem with one of my classes in an Eclipse Dynamic Web Project. I compile the war, save it to /webapps, startup Tomcat, see the war deployed. The only problem is that one of my classes (the one I use to query a PostgresSQL db) does not appear to be updating. I see the file update in the WEB-INF directory of the deployed war but the code that is running is not the code in the class. Namely it runs a SQL query that doesn't exist anywhere in class any longer - giving me a SQL error every time it's run.
Also, system.out.println statements in all my classes are showing up in the console except for this one class.
I'm using the Apache bundled with JUDDI (Tomcat 5.5). This one has me seriously stumped.
In a word: bounce the server. It sounds like an older version of the .class file is cached, so your new one isn't being loaded.
UPDATE: Since you've bounced the server, I'd say you should simplify the problem by taking out things that are unnecessary until you can make it work - because this does work.
Don't use Eclipse. Build, package, and deploy your WAR by hand to Tomcat outside of Eclipse. Start Tomcat in a shell using the startup script. See if it picks up your new class.
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??
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.