session beans belong to an application? - java

I have a newbie question as it relates to EJBs. When we compose a web application, all the jsp's/servlets etc are organized/packed into a war file which is deployed on to the server, when it comes to session beans and their deployment, are they treated as container level components that dont belong to any individual application?

No, they're not. EJBs should be packaged into a JAR (so called EJB-JAR) and then assembled into an EAR (that wraps EJB-JAR(s), WAR(s) and RAR(s)). Packaging EJB 3 Applications is a very good article (from the authors of EJB 3 in Action) on this topic and covers classloading, packaging and deployment of Java EE modules. Highly recommended.
Since Java EE 6, it is possible to deploy EJBs as part of a WAR (either put EJB-JARs in WEB-INF/lib or the classes directly in WEB-INF/classes). Note that all the classes are then loaded with the same classloader in this scenario (contrary to the EAR packaging). If you don't have strong modularization needs (which is the case of most applications), this is very interesting because simpler. Of course, the EAR packaging is still available for those with more advanced modularization requirements.

Related

Should I package my app into wildfly/jboss modules? (or any Java EE server equivalent tek)

I have taken over a large EE app which was mostly deployed as wildfly/jboss modules. There are separate apps off-course, and then there are this large number of modules.
Now, I get it - the intent is to share these components between multiple apps deployed on your server. But this also tightly couples these modules and to all of these apps. Also, Wildfly/JBoss has the facility to load dependencies from other modules, and each deployment is a module. Why should I package anything into the wildfly/modules/system/layers/base directory? Why not just deploy wars and ears as wildfly/standalone/deployments and define inter-module depdencies there?
What is the best practice? What am I missing here?
Deploying code in my own deployments allows it to be shared between multiple other deployments and allows for hot deployment.
It is never a good idea place your code within the wildfly system modules.

Create single web app (WAR) from multiple web applications

We already having an spring web application (maven project) say webApp1 which is hosted on production and working fine but now due some business requirements we want to develop an another web application say webApp2.
So some clients demands both apps, or some either one of them. we need freedom of which module to be deployed, there can be the case where some clients don't want webApp1 so deployment package must include only webApp2 or sometimes both.
Approach 1:
Lets create another maven project and develop individually, at the time of creating deployment package use of Apache Ant can be done which will create WAR file by combining libs,views,controllers of both the applications or of one. combining web.xml,root-context.xml,servlet-context.xml may be the manual task.
Approach 2:
After searching on approach 1 I come to know about EAR (similar question https://stackoverflow.com/a/2936464/1629242).
EAR package (similar question https://stackoverflow.com/a/2936464/1629242) can be the approach, but for this do I need to convert existing application as EAR? or what changes are required in existing working web application webApp1? also how I can control which module need to be added in EAR
As for approach 2. it really depends how exactly do you host your application, what is the container. If it's Tomcat/Jetty which can be a pretty common choice, than EAR is not even an option, since they don't "understand" (can't process) EAR files.
Regarding approach 1. The 'manual' part of combining various xmls can be tedious and certainly error prone. Moreover, if you combine the xmls you won't get a real separation (at the level of classloader) between webapp1 and webapp2. After all totally different applications will be hosted in the same WAR.
So, IMHO, you should go for approach 3:
Keep webapp1 and webapp2 as different deployment units (different WARs). Keep different web.xml, spring configuration files and so forth.
Deploy these wars as 2 different files in the same container. Container will happily serve 2 different Wars. This way, spring beans, servlets, filters and so forth won't interfere between two apps at runtime. Moreover this approach can be fully automated.

About Java EE deployment style, which is better?

I have a project, b/s architecture. and with EJB.
So, I can deploy it in two package: a war, and a ejb-jar.
and also, I could deploy it in ONE package: a EAR.
what's the advantage of deploy those two package to ONE ear ?
For me the following quotation (taken from the book "JBoss at work") explains it very well:
An EAR is like a carton of eggs—it keeps everything organized. While the carton doesn’t
add any direct value to your omelet, it makes getting the eggs home from the store so
easy that you wouldn’t think about transporting eggs any other way.
Each egg in your EAR carton is a specific piece of the J2EE puzzle (WAR, EJB, JAR).
edit as suggested by #DavidWallace find a refined answer below...
There is no such thing as an "advantage" of an EAR.
PRO: You can put everthing thing you need to deploy into a single archive.
CON: If you include a vendor specific deployment descriptor (for easy deployment) you might need to repackage the EAR if you want to deploy it into an application server from a different vendor.
At the end it's only a matter of assembling/packaging if you use an EAR or separate modules. Independent from that there is no extra coding needed.
Just my 2 cents to discussion here. If there is dependency between modules (e.g. war components are calling EJBs) I'd vote for single ear deployment, because:
easier management (single install/uninstall, start/stop) and a bit more logical (if you stop just ejb-jar, your web module wont work anyway.
can share some classes via util jars in ear/lib folder instead of duplication in each module or creating external shared lib
can use local interfaces and auto binding of #EJB references
Two separate modules would be better, if:
ejb-jar is shared by many independent applications (web modules) (kind of shared, service layer)
you would like to update web module without affecting ejb module.

What is correct about packaging a Java EE application

I am reading Beginning Java EE 6 with GlassFish 3 and I am confused about what is correct about packaging a Java EE application.
EJBs Lite can be pacakaged directly in a war or in a jar file. If you need to use the full EJB specification (e.g., remote interface, JMS, asynchrounous calls...) you have to packaged it inot a jar, not a war.
What does this mean? If I deploy an application packaged as a WAR in Glassfish, doesn't it give me all the Java EE services? If so what am I missing.
I understand that 3.1 introduced a new profile EJB Lite which is intended to be a subset of the full specification was targeted to implementors which doesn't want to implement everything, and that you from 3.1 can package EJBs in the WAR and use the services specified by the EJB Lite spec. But if you deploy a WAR in a full spec container it should give you everything as it would if you had created a JAR? Isn't a WAR just another name for a JAR? The distinction can't be on how it is packaged but what it actually supports?
Could somebody clarify.
The motivation of putting EJB logic beans in JAR files comes from a separation between business logic and view logic. At this time, as far as I am aware, there is no need to package all the EJBs into JAR and then combine this JAR with a WAR into EAR.
But... since EJBs are supposed to concentrate only on business logic, it makes sense to package them in a separate archive. WAR on the other hand is an archive of all things related to showing the GUI to the user, so JSPs, Facelets, images, CSS files and JavaScript libraries. WAR files can have a set of Classes in a WEB-INF\classes folder, as well as their own libraries in WEB-INF\lib. WAR file does not have to be a file, anyway. WAR file can become an exploded WAR, basically a directory with the same structure as it was in the archive.
A key aspect of that comes to class loader isolation in the class loader hierarchy. The WAR module has access to resources in EJB archive (JAR) and EJB module can reference and access resources (libraries) in the EAR file itself. The other direction, specifically an access to WAR resources from EJB module, is prohibited. And it is that way by design, as it prevents the developers - working under pressure - to mix those concerns and create a spaghetti code. Business Logic should be separated from View Logic, as it can and should be reused by Java SE clients, different Web Module clients, JAX-RS or within SOA based solution. If the business logic had any dependencies among JSFs or Servlets, using them in Java SE desktop solution would be impossible.
So, having a structure of EJB archive, which consists of many JAR and WAR files may not be necessary, but it is a best practice and one should be careful and concious about violating that rule.

How does a web server/container treat a POJO in respect to other classes like EJB's and Entities?

I'm trying to use plain old java objects(POJO)'s and regular class files where needed and only use EJBs when I need the functionality that they add such as asynchronous calls, pooling, etc. I'm wondering how the server treats this behavior once the project is deployed on a server. Since it is not managed by the container does a new instance have to be created for every stateless session bean pooled that might call one of it's methods? How do things like static methods or state affect this model.
Edit:
1) I can clarify more. The point of Java EE is that you annotate a POJO with #stateless etc so that a container can manage it. You don't have to declare a new instance of a stateless bean you just inject and can make calls to it's type.
2) Most Java EE tutorials and books never mention non annotated classes as a part of your business logic. It's never brought up. This seems strange to me if you can use them in Java EE projects for your business logic and it can get deployed on a server. If you don't need pooling or asynchronous access--the things that a container helps manager through an EJB then you can use theses regular POJO's in your Java EE project.
3) that leads me to my question which is how do I incorporate properly into a project? Do I put them in the EJB project that's connected to an EAR or should they go in the EAR? or Dynamic web project. There is almost no mention or instruction on proper use of regular objects like this. When it gets compiled into a WAR for deployment are there any issues you run into on the server? Isn't it expecting properly annotated EJBs, servlets or JSP?
The don't affect it at all. Classes are classes, objects are objects. They're no managed, they're not interfered with, nothing happens to them. They're not special is any way.
Static singletons are static singletons, Java is java.
All you need to be aware of is the classloader layout of your container, and how it relates to your deployed applications and resources. (Classes in one app can't see classes in another app, for example.) Most of the time it's not really important. Sometimes, it is, as things get more complicated.
But for the most part, it's just Java.
Addenda:
A better way to look at this is to simply group your classes up in to blocks of locality.
Let's take a simple web app that uses EJBs.
The web app is deployed in a WAR artifact, and the EJBs can be deployed separately, as individual EJBs in the container, or, more likely, in an EAR. When you package your application in an EAR, you will likely bundle the WAR within the EAR as well. So, in the end the EAR contains your WAR, and your EJBs.
Now during development, in this case, you're going to have classes that have are in one of three categories.
Classes that are relevant solely to the EJBs (for example the Session Beans).
Classes that are relevant solely to the WARs (such as a Servlet class).
Classes that are relevant to both (a database entity perhaps).
So, a simple way to package them is in three jar files. A jar file for your WAR (in fact, this is the WAR, with the classes in WEB-INF/classes), a jar file for your EJBs, and a jar file for the 3rd type, we'll call that a library.
In terms of build dependency, the WAR build depends on the lib, and the EJB build depends on the lib. But neither the WAR nor EJB depend on each other, as they don't share anything directly, only indirectly through the 3rd library jar. The lib jar is stand alone, since it doesn't have any dependency on either the WAR or EJBs. Note, your EJB Session Bean interface classes will go in to the library jar (since both tiers rely upon them).
In your ear, you simply bundle the lib jar, the WAR, and the EJB jar along with a META-INF dir and an application.xml file. The WAR has its own structure, with the WEB-INF and all, the EJB jar has its META-INF and ejb-jar.xml. But of note is the that lib.jar is NOT in the WEB-INF/lib directory, it's in the EAR bundle and thus shared by both the EJBs and the WAR using class loader chicanery that the container is responsible for.
This is important to note. For example, if you have, say, a simple static Singleton in your lib jar, then BOTH the WAR and EJBs will share that Singleton, since they're all part of the same class loader. To use that Singleton, it's just normal Java. Nothing special there.
If the EJB and WAR were deployed separately, they would EACH need there own copy of the lib.jar, and in the case of the Singleton, they would NOT share it, since each module would have it's own class loader.
So, barring some real burning need otherwise, it's easier to bundle everything in to an EAR and treat both the EJB tier and WAR tier as a single, integrated application.
Addenda 2:
People don't much talk about using classes in Java EE development because there's nothing to talk about, they just use them, like in any Java program. You're over thinking this here.
The 3 jar idiom: war, ejb, lib is one I've used over the years because it separates the 3 concerns, and limits dependencies. Client -> lib -> EJB. It also simplifies the build, since clients typically need just the lib jar and java. In the Netbeans IDE, this is trivial to manage. With minor work, it's straightforward in other IDEs or even in ant/maven. It's not a huge burden, but keeps the 3 parts relatively clean.
Dependency and Jar management is the nightmare of any large Java project, and even more so with EJB when you're dealing with the different deployable artifacts. Anything that can help mitigate that is a win, in my book, and truth is, a clean, stand alone lib jar helps a lot, especially of you need to integrate and use that lib with other code. For example, if you later write an external GUI client using Remote EJBs, or even web services, the lib jar is the only dependency that client has. The benefits of this jar far outweigh the minor pain it takes to set up this kind of library.
In the end the lib jar is just a jar like any other jar you'd want to use in your application (like logging or any other popular 3rd party jars).

Categories

Resources