We're deploying our JavaEE 7 application on Wildfly 8. Previously, we've packaged all of our enterprise applications (WAR, multiple EJB JAR files) as an EAR. However, with JavaEE now allowing you to package EJBs in a WAR file (or as a JAR within the WAR's WEB-INF/lib) we're wondering if there is any benefit in deploying an EAR rather than going with WAR packaging.
Does an EAR provide something that a WAR does not? It certainly reduces packaging complexity to make use of a WAR. Is there any difference in terms of deployment? EJB naming? Anything?
Easier to deploy (only one package instead of multiples).
Some server (example Weblogic, but not wildfly) allow shared session for an entire EAR.
In general, EAR provide more option to configure with AS.
Special folder (APP-INF) that let you define a config file application.xml.
If your application would consist only of multiple WARs then you may not find it such a big deal to maintain multiple deploy. However, consider an application which use WARs, EJBs, JMS etc. It will be a lot easier to mananage the interaction between all these components in an EAR.
You might want to read the packaging application part of the Java EE tutorial.
Setup of deployment of an EAR is painfully hard work (especially under Weblogic). Deployment of a WAR is simpler. Deployment as EAR has two benefits:
You can aggregate several unlinked applications in one file (whole eggs in one basket).
You can reduce size of this file with help of skinny war technology.
Your devops can deploy only one application instead of several.
Links restoring is not needed.
You can setup a well build barrier between in\out ear modules.
And many many others.
In other words one-war pattern in most of cases is devoted only for test and training purposes.
Related
What I understand is we can deploy a spring-boot application as a jar and as a war as well. What I don't understand is when should we go with a jar and a war ? I am talking about spring-boot web apps.
stack overflow
Both ways are equivalent technological wise.
JAR is a preferable way of deploying spring boot application, so consider it it as a first bet.
WAR is required if you already have java web servers (tomcats) managed by people who don't want/need to adopt a new / another way of deployment.
Usually this happens in large organizations or organizations with a dedicated IT / adminstration/ops department (many names exist for this), but essentially these are people who are responsible for deployment of the application.
I currently set up a Java EE project for a new business application using CDI. The application is a pure server application (using jms, webservices and such, but has no frontend).
Since we are using Java EE 6, I would like to use the new WAR packaging instead of the former EAR, which seems to be a simpler packaging mechanism to me and was recommended to use if one has no special modularization needs.
My problem in understanding is now, that I am still thinking of a WAR as a web application. How is the project layout in my case, do I still have for example a WEB-INF folder even though I don't have any frontend and there's no need to publish the application under a context? Or is there a better way to structure a pure server application?
The 'new WAR' has the same layout as the 'old WAR', the only difference is that the EJB JAR(s) can now be placed inside the WEB-INF/lib folder of the WAR. In the 'old WAR' you could not place EJBs inside the WAR.
I have a JavaEE6 application, consisting of Web stuff and EJBs and which is deployed as WAR-only (using EJB3.1). The build is based on Maven. I just read about a new possibility to order the module initialization in Java EE 6 here which i also need for my application. Also, i would like to have an option to define some EJB properties in XML.
Since the example is deployed as an EAR-project the order is defined in the application.xml. But in a WAR-deployed project, there is no application.xml. Now i wonder where i can define such informations? Or is it possible to use an application.xml somehow in a WAR-deployed-app?
EDIT:
Oops i didn't read the module-order-example right, in the first moment i thought it was about in which order the EJBs in my app are loaded. Of course i have only one module in my WAR-app, so ordering makes no sense.
Ok, but as i'm at it, one big question remains (also altered the question title to reflect the change): What about the ejb-jar.xml? Can i somehow define stuff about my EJBs in XML (as its useful for some settings, to avoid recompilation)?
In short, it is not possible with a WAR based deployment.
The module initialization feature of Java EE 6 is meant for initializing different modules of an application in a specific order. The moment you have a WAR based EJB application, you no longer have separate modules for your EJB and Web application. There is just one module - the web application module in a WAR based deployment.
Therefore, if you have to achieve the same feature as the module initialization order, offered in Java EE 6, you'll have to do either of the following:
Separate the EJB into a separate module, and use a EAR based deployment.
This is more or less trickery, as was done in Java EE 5, and you would want to be avoiding it. You might want to code in logic to ensure that the singleton EJBs have been created (assuming that this is due to the use of singletons in your application), before they're utilized in code.
Location of the ejb-jar.xml in a WAR file
The EJB 3.1 specification (in the chapter on Packaging) addresses the issue of the location of the ejb-jar.xml file when deployed in a WAR:
In a .war file, the deployment
descriptor is stored with the name
WEB-INF/ejb-jar.xml.
PS: I haven't tried this style of deployment yet. YMMV.
Side note on EJBs in .wars and ejb-jar.xml processing. As already noted the location is WEB-INF/ejb-jar.xml, but also note that is the only location checked even if there are ejbs jars inside WEB-INF/lib/ -- via standard rules any META-INF/ejb-jar.xml files there are ignored.
The Expert Group was rather split on that one, so if you have a preference it's not too late to send feedback to the EJB 3.1 expert group list for consideration in EJB.next.
My vote was to still allow individual jars to have META-INF/ejb-jar.xml files just as these jars can now have persistence.xmls, beans.xmls, web fragments etc. The larger issue for me was that it is at odds with the Embedded EJB Container API which supports an EAR-style classpath which allows several jars/modules each possibly containing a META-INF/ejb-jar.xml file. The result being if you do use the Embedded API to test a multi-jar ejb app that is composed into a single .war file, you are then faced with the task of merging any ejb-jar.xml data you have into a single ejb-jar.xml for the webapp. Sort of a pain for users.
We have many Spring web applications to make on a WebLogic server and are curious about when WARs should go in an EAR and when they should just exist as WARs. Occassionally, the WARs will need to access common logic JARs, but I don't see why these would need to go into an EAR when they could just be packaged into the WARs.
From what I understand, if several WARs are in an EAR and you need to modify one of those WARs, you need to redeploy the entire EAR to update the server. This will cause all of the WARs to bounce. If they weren't in an EAR, however, I could just update the one WAR and it would be the only one to bounce.
What's wrong with having 100 different WAR files standing alone and using packaged JARs and shared libraries (using WebLogic)?
Thank you for any insight!
If all you have is WAR files, then an EAR is of limited usefulness, serving only as a deployment container for your WARs. You can save a bit of bloat by sharing JARs between the WARs in this way, but that in itself is not hugely compelling.
EARs are essential, however, when dealing with full JavaEE/J2EE applications, which use WARs, EJBs, JMS, JCA resources, etc. The interactions and dependencies between the components of these sort of applications is vastly easier to manage in an EAR.
But if all you're using Weblogic for is a WAR container, then you might as well use a vanilla servlet container like Tomcat or Jetty, for all the functional use you get out of Weblogic.
I agree with almost all of skaffman's (typically) spot on comments.
If you're using Spring without EJBs you can stick with a WAR file, of course. No need for an EAR that I can see.
However, if your Spring app uses message-driven POJOs I can see where you'd still deploy a WAR file on WebLogic to take advantage of JMS.
An EAR might be necessary if you've got EJBs or JCA, but I wouldn't say that JMS mandates an EAR. I've used JMS and deployed a WAR file on WebLogic and it's worked just fine.
If you decide to go with Tomcat and deploy a WAR there, you can still keep JMS functionality if you use ActiveMQ.
The argument to package multiple WARs into an EAR can be compelling if you run into the situation that my last employer did, where you have a common set of library JARs that are used by multiple WARs, and the size of that collection of JARs is considerable. In our particular situation, the total size of 3 WARs with the common JARs packaged into each WAR totaled 124MB. By locating the JARs in the containing EAR and configuring the classpath of each WAR to use those JARs, the footprint of the EAR that contained the 3 WARs was reduced to 40MB. I'd consider that a compelling reason.
Having multiple shared libraries rather should not be the compelling reason to go for an EAR, as a JAR (or set of JARs) can always be deployed as "library" on weblogic which can, therefore, be shared by all the WARs. Isn' it right?
Nothing is actually wrong with just deploying wars, developers have an interest in getting tasks met quickly as possible. That means they often will take on technical debt, and if they are in a respectable team, they will clean that debt.
This however presents a problem, what happens when you avoid the complexity of EARs, and share a jar by adding it to the application server? Much more common in the war only team, is offloading all sorts of application complexity to the application server. Simply because it was easier to implement, in their often over-allocated schedule. I don't blame them for this at all, However now we have a new problem. A standard application server cannot be used, you must do system side customizations. Effectively the web application is bleeding all over the system. The person who maintains the Application server, now MUST also know application specific details... in an enterprise environment, this presents a very clear problem.
The developers can then take on system responsibility, but they still need to meet deadlines. They inevitably bleed all over the OS as well, and suddenly the developers are the only possible admins. If an admin doesn’t know what the application is using system side, they can very much cause major problems. These unclear lines always end in fingers pointing in both directions, unknown system states, and team isolation.
Do they have to use an EAR then? Nope, I'm a systems Engineer, so I always say they can deploy their own application server like another commercial application. Inside an RPM, if deploying a WAR is like other supported Application Servers, then they get the WAR deployment pipeline. If not, then RPM all in one... Once not allowing the team to externalize their costs, then EARs become a GREAT idea.
At our shop, we are maintaining roughly 20 Java EE web applications. Most of these applications are fairly CRUD-like in their architecture, with a few of them being pretty processor intensive calculation applications.
For the deployment of these applications we have been using Hudson set up to monitor our CVS repository. When we have a check-in, the projects are set to be compiled and deployed to our Tomcat 6.0 server (Solaris 10, sparc Dual-core 1.6 GHz processor, 2 GB RAM...not the beefiest machine by any stretch of the imagination...) and, if any unit-tests exist for the project, those are executed and the project is only deployed if the unit-tests pass. This works great.
Now, over time, I've noticed myself that a lot of the projects I create utilize the same .jar files over and over again (Hibernate, POI (Excel output), SQL Server JDBC driver, JSF, ICEFaces, business logic .jar files, etc.). Our practice has been to just keep a folder on our network drive stocked with all the default .jar files we have been using, and when a new project is started we copy this set of .jar files into the new project and go from there...and I feel so dirty every time this happens it has started to keep me up at night. I have been told by my co-workers that it is "extremely difficult" to set up a .jar repository on the tomcat server, which I don't buy for a second...I attribute it to pure laziness and, probably, no desire to learn the best practice. I could be wrong, however, I am just stating my feelings on the matter. This seems to bloat the size of our .war files that get deployed to the server as well.
From my understanding, Tomcat itself has a set of .jar files that are accessible to all applications deployed to it, so I would think we would be able to consolidate all of these duplicate .jar files in all our projects and move them onto the tomcat server. This would involve only updating one .jar file on the server if, for example, we need to update the ICEFaces .jar files to a new version.
Another part of me says that by including only one copy of the .jar files on the server, I might need to keep a copy of the server's lib directory in my development environment as well (i.e. include those .jar files in eclipse dependency).
My gut instinct tells me that I want to move those duplicated .jar files onto the server...will this work?
I think Maven and Ivy were born to help manage JAR dependencies. Maybe you'll find that those are helpful.
As far as the debate about duplicating the JARs in every project versus putting them in the server/lib, I think it hinges on one point: How likely is it that you'll want to upgrade every single application deployed on Tomcat at the same time? Can you ever envision a time where you might have N apps running on that server, and the (N+1)th app could want or require a newer version of a particular JAR?
If you don't mind keeping all the apps in synch, by all means have them use a common library base.
Personally, I think that disk space is cheap. My preference is to duplicate JARs for each app and put them in the WAR file. I like the partitioning. I'd like to see more of it when OSGi becomes more mainstream.
It works most of the time, but you can get into annoying situations where the jar that you have moved into tomcat is trying to make an instance of a class in one of your web application jars, leading to ClassNotFoundException s being thrown. I used to do this, but stopped because of these problems.
I really don't think putting libraries in common/lib is a good idea. The idea behind the use of war files as applications into a servlet container, is to have a real idea of isolation between your webapps. You could face errors like deploy some third party WAR (with it own libraries inside WEB-INF/lib) and it behave unexpectedly because it loaded other version of one of it libraries from the common one (remember that the regular behavior for load classes is first look at the common classloader and if you don't find the class look into the one for your webapp). Don't even mention how painful could be to move some application to other servlet container or an Application Server.
As mentioned before, you could use maven to deal with jar dependencies, and if you like the homogeneous use of libraries, define a POM parent (maven jargon) across all your applications.
In my experience you should be very careful with sharing libraries between web applications by moving them into the web container itself.
Let them live in WEB-INF/lib so your wars are self contained (you WILL be glad you did one day).
What you might consider is employing maven or Ant Ivy to pull in library jars from a common repository instead. This is very useful and should not be a problem in your scenario.
Edit: A notable exception is the Metro library - web service layer from Glassfish - which needs to be in the web container and not in the web application.