In a .ear file, my EJBs are copied in several jar and war for some technical constraints. And only one of these jar contains the persistence.xml file where I have configured several persistence units.
myear.ear
|---- myjar1.jar
|-------- META-INF/persistence.xml
|---- myjar2.jar
|---- mywar.war
The problem is Jboss cannot find the persistence configuration for the classes within the jar "myjar2" and the war :
Could not get class configuration for ....EjbA.class due to the following errors: Can't find a deployment unit named xxxxx at
subdeployment "jar2.jar" of deployment "myear.ear"
To resolve that, I tried to create a new jar containing only the persistence.xml file but it doesn't work.
Any idea of how I could share my persistence.xml file to every jar without reorganising all my ear archive?
As per the JPA spec, it should be possible for you to define a persistence unit at the EAR level that is visible to all the submodules that you define in the same .ear:
8.2.2 Persistence Unit Scope
...
A persistence unit that is defined at the level of the EAR is
generally visible to all components in the application. However, if a
persistence unit of the same name is defined by an EJB-JAR, WAR, or
application jar file within the EAR, the persistence unit of that name
defined at EAR level will not be visible to the components defined by
that EJB-JAR, WAR, or application jar file unless the persistence unit
reference uses the persistence unit name # syntax to specify a path
name to disambiguate the reference.
However, in section 8:
NOTE: Java Persistence 1.0 supported use of a jar file in the root of
the EAR as the root of a persistence unit. This use is no longer
supported. Portable applications should use the EAR library directory
for this case instead. See [9].
So I would try to place the jar in the lib folder. If you need that module to be a EJB one, it must be in the root of the ear, so you can create a separate jar with the persistence.xml file.
Related
I have an enterprise application packaged as:
EAR
WAR1
WAR2
ejb.jar
lib/core.jar
lib/module1.jar
lib/module2.jar
...
lib/moduleN.jar
WAR packages are optional and every moduleX.jar contains a spring-bean.xml configuration file.
I need to load the spring context in the core.jar and share this context between WARs. Since i don't know how many modules are packaged, i need to load the xml files at runtime.
Thanks for help.
I have this problem. I want to load a properties file located in a war file but the class loader is in another jar file. But they are compiled in one ear file. When I place the properties file in src folder of the jar file's project, it works but I wanted to put it in Web-INF/Classes for future update purposes.
Details.
Compiled in EAR
EJB
IBM Websphere
Thanks!
You war depends on your EJB but the EJB does not depends on your war.
Thus, it's not possible.
If configuration must be updated, you should externalize it.
You won't be able to modify files in your war.
A good practice is to generate EJB jars and WARs independtly of the environment.
It will enable your Exploitation team to deploy the same code in every environment. They will just need to adapt the externalized property files (DB login / password, etc...).
Do I package a stateless session bean in a war file or a ear file for deployment?
Neither nor. EJBs belong in standard JAR files (with a META-INF/ejb-jar.xml). In order to use EJBs from a WAR you pack these two archives in an EAR.
Since this is not really convenient it's possible since EJB 3.1 to package EJBs in the WAR.
Stateless Session Beans (SLSB) are packaged in an EJB-JAR (which is a regular JAR file) including or not an optional deployment descriptor. EJB-JARs and WARs are assembled in an EAR for deployment.
See this article by Debu Panda and Rezza Rahmann (which is actually an extract from the excellent EJB 3 in Action):
Packaging EJB 3 Applications
With EJB 3.1/Java EE 6 you don't need EAR files any more, you can also put your session beans directly in a WAR file (as a separate .class file in WEB-INF/classes, or inside a JAR file within the WAR file's WEB-INF/lib directory). See e.g. http://java.sun.com/developer/technicalArticles/JavaEE/JavaEE6Overview_Part3.html#simpack
My goal is pretty simple: to use ant to build an EAR which contains 1 EJB and 1 jar containing all of the dependencies. This jar, called common.jar for the sake of example has vendor jar files in it as well as other xml files that the EJB depends on and will need to be able to see during runtime....
So far I have everything packaged correctly as an EAR like this:
EARFILE.ear
-EJBFILE.jar
/META-INF
-MANIFEST.MF
-common.jar
/META-INF
-MANIFEST.MF
/lib
-(all vendor jars inside here)
-(All the xml config files are inside the root of the common.jar)
Inside the MANIFEST.MF for the EJBFILE.jar is...
Class-path: ../../common.jar
Inside the MANIFEST.MF for the common.jar is...
Class-path: ../lib/some_common.jar
When I deploy this the appserver (websphere) cannot find the JAR file when I try to start the server. I am getting the ClassDefNotFoundError because the classes inside the EJB cant find the vendor JAR files when I try to start the instance. However I know that common.jar is setup correctly though, else the EJB wouldn't have compiled since it needed to have those vendor jars on the classpath for javac.
So what I want to know is this:
How can I get the runtime to correctly see the Vendor jar files.
Will the EJB be able to see the xml files at run-time? I am concerned about this because these xml files are located outside of the EJB inside of a jar that is just in the EAR, it isn't even a module its just a jar inside the EAR.
Does it even matter when using websphere? From what I gather some containers don't even care what is in the Class-path of MANIFEST.MF.
There are several improvements I can suggest, based on running into similar problems.
First and most importantly, use the appxml attribute of the Ant ear task to specify your deployment descriptor (usually named application.xml); also include references to the vendor JAR files bundled as defined below
I would recommend you not put your vendor JAR files into another JAR - instead, just copy them into the EAR at the same level as EJBFILE.jar
The configuration XML files can go in a sub-directory of the EJBFILE.jar (such as config), and then you can reference them as /config/filename.xml.
The application.xml file will tell WebSphere where to find your JAR files. Classpath traversal in an application server is not the same as that of a compiler, which JBoss has taught me the hard way.
I am using all of the above patterns, and my in-container code (deployed in the EAR) can see all my XML files, as well as find all my dependencies.
I have an ear which consists of 2 war files one containing junit classes and the other one containing actual application classes which are referenced by the junits.
Now when executing the junits i get a java.lang.NoClassDefFoundError
Is it due to the junit class files are located in different ear and hence not able to access the application class files that are located in another ear ?
OR
Whether this is due to the issue with deployment, Though i am able to run the application as well as some of the junits which are independent of application classes located in the other ear ?
According to the strict JavaEE visibility semantics, classes inside a WAR should not be visible to other components of the same EAR. JBoss relaxes this a fair bit, and tries to flatten out the classloading hierarchy to make it less irritating, but the WAR restriction still stands.
The solution I use is to put only web resources into the WAR, and to put the WAR's class files into a seperate JAR inside the EAR. That way, the webapp itself can find the classes, and so can your unit test webapp.
The correct way is to move the common classes into a dedicated JAR, and bundle that at the EAR level. So you will have a structure like this:
business-logic-jar
main-web-app-war
test-web-app-war
application-ear
You can bundle the JAR as well as any other libs you depend on in your EAR, and reference them using the manifest file of your WARs. In MANIFEST.MF it looks like:
Class-Path: business-logic-1.0.jar spring-2.5.5.jar ...
You can still bundle additional JARs inside each WAR's WEB-INF/lib folder, e.g. junit inside the test-web-app-war. If you are using Maven, read the skinny war page for a general approach.
JUnit classes don't belong in WAR or EAR files. They shouldn't be deployed.
You don't say which app server you're using, but if you use WebLogic you can put all your .class files into APP-INF/classes. They'll be visible at the EAR level then, so all WARs can see them.