What is correct about packaging a Java EE application - java

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.

Related

How to make a class available to Spring within Tomcat?

I'm working with an application which has a modular architecture - each module is contained in a WAR file running on top of Tomcat. One of the modules allows users to extend its functionality with a request Interceptor interface, which is #Autowired into the class by Spring.
I'm working on a custom Interceptor and would like to make it available to Spring for autowiring within the module. Until now I've been building a custom version of the module's WAR which contains my interceptor, but I do not feel that this is a clean approach because the idea was to make the application easily extensible, and building my own fork for this reason seems to almost eliminate the benefits of the Interceptor interface.
I know one possibility is to crack the WAR open (it's just a ZIP archive) and drop a custom JAR in there, but that doesn't feel right either. Perhaps there is a way of adding custom JARs using Maven? Is there an industry-standard way of doing this?
I think I have at least a partial answer, everyone is welcome to provide a better one.
There is a helpful documentation page about class loading in Tomcat. It describes where classes are loaded from, snippets which are most interesting to a casual reader are reproduced below:
unpacked classes and resources in $CATALINA_BASE/lib
JAR files in $CATALINA_BASE/lib
unpacked classes and resources in $CATALINA_HOME/lib
JAR files in $CATALINA_HOME/lib
WebappX — A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the /WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the /WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.

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.

How to run one JSF WAR file in second JSF project?

I am working on project in JSF, using Tomcat 7. The application will have two parts - the presentation and the administration, main part is about the administration. What I want to do is to create something like a web library.
To have this more clear, I'll try to show structure of the project:
The main application project (let's call it admin) that is builed into WAR file.
Second project using the first one (let's call it presentation).
Presentation is using the admin WAR file.
both projects are typical JSFs - admin has pages, beans, etc.
In NetBeans, I have no problem with adding WAR file as a library, but, there are two things. The first: are all ManagedBeans in admin initialized together with presentation run, so I can use them in presentation? The second: how do I access pages from presentation that are located in admin?
Maybe I am wrong about this idea and I should use different way how to achieve this - so just tell me please.
Also, I probably will not be able to deploy two war files and run them - most of the hostings where the application will run allow deploying of one WAR file only.
Make it a common JAR instead of WAR, so that you can include it in both WARs. This way you can share managed beans and templates between both WARs. The Facelets resources can just be placed in /META-INF/resources of the JAR. The JSF artifacts like managed beans will be auto-discovered if you provide a /META-INF/faces-config.xml file.
See also:
Structure for multiple JSF projects with shared code

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).

session beans belong to an application?

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.

Categories

Resources