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
Related
I have an Enterprise project (EAR) with one EJB and several web modules, these web modules have lots of classes in common, they are exactly the same for each project, so if I modify one of them I'll have to manually copy the code to the other projects as well. I don't want to put them in my EJB module because they use a lot of front-end related resources.
Is there a way to share these classes between the web projects?
Obs: They also use classes and resources from the EJB module.
Make another module with all commun classes and package it as a Jar. Then add the jar as a dependency to the other project.
Maven should be a good tool for this project.
There is no way to have shared classes outside of a .war which are capable of having web-specific resources injected.
I would refactor the common classes into a separate .jar. You could make them EJBs, or just regular classes. Either way, you won't be able to inject web-specific resources; the classes in .wars will have to pass such things as method parameters. In the case of EJBs, you can't directly pass non-serializable objects like HttpServletRequests; I don't know if that will create a significant impediment.
An EJB .jar can be placed anywhere in the .ear, but if you choose to make a non-EJB .jar, it can be placed in the lib directory of your .ear file. It's also a good place for EJB interfaces, if you aren't writing no-interface EJBs. From the Java EE specification's "Application Assembly and Deployment" chapter:
A .ear file may contain a directory that contains libraries packaged in JAR files. The library-directory element of the .ear file’s deployment descriptor contains the name of this directory. If a library-directory element isn’t specified, or if the .ear file does not contain a deployment descriptor, the directory named lib is used. An empty library-directory element may be used to specify that there is no library directory.
All files in this directory (but not subdirectories) with a .jar extension must be made available to all components packaged in the EAR file, including application clients. These libraries may reference other libraries, either bundled with the application or installed separately, using any of the techniques described herein.
When I use Tomcat,
the common utilities are packaged as JARs in tomcat/lib
because every WAR has its own class loader,
and classes and libs under the WEB-INF/lib directoy of the WAR is not visible to other ones.
When I use Jboss,
the common utilities can packaged not only as JARs in jboss/lib but also as EJB JARs (invoked as services)
When I have some classes as common services, I can put them in JARs as well as EJB JARs.
I have no idea about the difference between JARs and EJB JARs from a usage perspective.
Can anyone guide me to the right path?
The difference is clear when you see the difference between the contents of a JAR vs a EJB JAR. Apart from the source files (compiled) and the manifest that a JAR file has, you'd also need the following (back in the pre-annotation days):
The XML deployment descriptor
The beans
The remote and home interfaces
Dependencies
This tells the container which are the EJBs and their home/remote interfaces so when a request asks for a bean, the container will know which one to invoke. Without these files, there is no way of you telling the containers (except annotations wherever applicable), that this the bean implementing an interface.
More information can be found at this url
I'm aware that this is a very simple issue, but as I'm new to Wildfly I haven't had success trying to accomplish it.
In the old days of JBoss 4.2, when I wanted to share an ejb jar file with multiple war files I just deployed the ejb jar file to the application server and configured jndi in my war projects with a file 'jndi.properties' placed in some source directory in the war files, like this:
jndi.properties
---------------
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099
Now, with Wildfly 8.1, this approach is not working anymore. I don't know if the contents of the jndi properties file changed or if I have to do something else. So, I ask: how do I share an ejb jar file with multiple wars in Wildfly 8.1 (I don't want to use ear files for this)?
Thank you in advance.
Marcos
PS.: Cross-posted: https://developer.jboss.org/thread/249133
just deploy the jar file and add adependency to your war file (either in Manifest.MF or in jboss-deployment-structure.xml from your war to your jar. Then you should be able to do JNDI-lookups using java:global/... or using CDI for injecting the beans using #Inject (for this approach you will need to activate CDI using beans.xml)
see also:
Wildfly class loading
Wildfly deployment descriptors
CDI reference
Application deployment
Greets,
Is there anyway to make the classes of a WAR available on the classpath of EAR archives, or on another WAR archives, without having to create a jar file with those WAR classes?
Cheers
You can do this via MANIFEST.MF entry 'Class-Path' in modules where you want to use classes from WAR. Or you can use vendor-dependent way(e.g. jboss 7 has modules-isolation parameter in deployment description jboss-deployment-structure.xml).
IMHO instead of exposing WAR classses to other modules, you should create JAR with common libraries, otherwise you will have really tight coupled modules in your deployment.
I have a JAVA EE Project, containing both EJB and WAR projects inside of it.
I want to be able to access WAR project class from the EJB project class.
I have access the other way ( I can access ejb class from war).
Is that possibble? How can this be done?
Thank's In Advance.
I assume that you have got an EAR with two modules inside, WAR and EJB JAR. As both modules are independent, they shouldn't depend on each other. What you want to do is possible via MANIFEST.MF Class-Path entry in module META-INF folder, but I strongly discourage you to do so.
You can re-factor you application to following structure:
EAR/
ejb-app.jar
war-app.jar
lib/
common-libraries.jar
Just putyour common libraries to separate JAR (regular java project), and add it to ejb-app and war-app classpath.
Alternatively you can implement EJB's in WAR project as they are supported in WAR since Java EE6.