aspose file tools*
The moose likes Ant, Maven and Other Build Tools and the fly likes maven: the war directory structure Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » Ant, Maven and Other Build Tools
Bookmark "maven: the war directory structure" Watch "maven: the war directory structure" New topic
Author

maven: the war directory structure

Syed Mahdi
Ranch Hand

Joined: Aug 27, 2004
Posts: 45
Hi All!

I am trying to use Maven on a project. I had a web app which was supposed to be packaged as a war.
Now in the beginning it packaged the war with the libs in a "lib" folder in the root. But i changed something and now its packaging it in inside the Web-Inf/lib folder.

actually the issue is that the requirement is to package the war in the ear file and the ear file is suposed to have the libs in its root for the war to use.

Am i missing something here. when i make an ear project and add a dependency of the war project even then the libs are not created in the ear they remain in the war.

may be i am not understanding something here conceptually:

Where are the libs SUposed to be in a war for its use.

Where are the libs supposed to be in an ear for the war to be used.

I was told that by someone that they are supposed to be in the root of the ear and not inside the war.

help me out on this one. Is there a way to acheive this (to have the libs of the war in the root of the ear)?

thanks
syed...
Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5842
    
    7

If the classes in a JAR file (other than EJBs) are required only by code in the WAR file, then they go into the WAR at WEB-INF/lib. In this case, you add the JAR as a dependency to the pom.xml that creates the WAR.

If you package EJBs into a JAR, then that JAR goes into the EAR, typically in the base directory. If the EJBs depend on classes in other JAR files, then those JAR files go into the EAR in the lib directory. See the Ear plugin docs for info on positioning the JARs: http://maven.apache.org/maven-1.x/plugins/ear/properties.html.

If classes in a JAR are used by both the code in the WAR and by EJBs, then place that JAR into the EAR in the lib directory.

For example, assume your web app uses the commons-collection classes, your EJBs use the commons-lang classes, and bot the web app and the EJBs use commons-logging. Then you EAR would be packaged as follows:

your_ejbs.jar
lib/commons-lang.jar
lib/commons-logging.jar
your_web_app.war
  + WEB-INF/lib/commons-collection.jar


JBoss In Action
Syed Mahdi
Ranch Hand

Joined: Aug 27, 2004
Posts: 45
Awesome answer : ( we should have a point system like stack over flow) for the detailed and going a mile ahead to answer the query.

So appreciate it.

Ok, I will really appreciate it if you or some can take the same kind of interest just like the previous answer:

My app is packaged in an ear which only has a war. (No Ejbs),So maven puts all the libs in the WEB-INF/lib folder automatically. this is the default behavior.

My Manager asked me to package the ear file so that the libs are out side the war package kinda like this:

ear
--/lib/
---*.jar
--app.war
---WEB_INF/lib/(nothing there)

Or out of the app.war/WEB_INF/Lib folder into the root of the war



1) How can i change this behavior in maven to package it like this?
2) how can i manually package the ear file like that and see in deploy if it works or not.


See, when I did built the ear file with the default behavior, and deployed it, it asked for some libs that weren't needed at compile time and threw class not found exceptions in runtime (like groovy-all.jar for some spring aspect j jar (sorry don't remember where it was needed exactly)) and logback-classic.jar (which was used by a local project jar in the war)) so we place them in the lib of the ear. So my manager said to remove the libs from the app.war/WEB_INF/lib and place them in either these two places

1) either in app.war/lib folder OR ( will it matter if it comes out of the WEB_INF folder)
2) in app.ear/lib folder (will the app.war not have any problems with this)

I am not able to test it cos i don't know exactly how can i package it to my requirement.

If you have any way that i can test this structure please tell me as well.

thanks again. and really appreciate the way the answer was detailed out.

syed...




Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5842
    
    7

You don't want to do this.

First, servlets must reside in the WEB-INF/lib directory. (Well, let me say I've never heard of them being outside of it.)

Second, WARs are not transparent, any classes residing in JARs outside of the WAR will not have visibility to classes inside the WAR. This can lead to class not found exceptions.

If you have some utility classes that you are sure won't need to call back into classes in the WAR, you can do it this way: you will need 2 projects, one to build the WAR, the other to build the EAR.

The POM for the WAR should indicate the "provided" scope for all of the dependencies that go into the EAR/lib directory. This way the compile can use them to compile your servlets, yet won't package them into the WEB-INF/lib directory.

The POM for the EAP would list the the JARs that go into EAR/lib as dependencies.

(That is sort of off the top of my head, I haven't tried it before and rarely build EARs)
Syed Mahdi
Ranch Hand

Joined: Aug 27, 2004
Posts: 45
Peter Johnson wrote:You don't want to do this.

First, servlets must reside in the WEB-INF/lib directory. (Well, let me say I've never heard of them being outside of it.)

Second, WARs are not transparent, any classes residing in JARs outside of the WAR will not have visibility to classes inside the WAR. This can lead to class not found exceptions.

If you have some utility classes that you are sure won't need to call back into classes in the WAR, you can do it this way: you will need 2 projects, one to build the WAR, the other to build the EAR.

The POM for the WAR should indicate the "provided" scope for all of the dependencies that go into the EAR/lib directory. This way the compile can use them to compile your servlets, yet won't package them into the WEB-INF/lib directory.

The POM for the EAP would list the the JARs that go into EAR/lib as dependencies.

(That is sort of off the top of my head, I haven't tried it before and rarely build EARs)


Hello !!

thanks for the reply. Servlets in lib? I thought they should be in WEB-INF/Classes/


Yes, I understand that Wars aren't transparent that's why i will go with the second option but a bit differently. (I am listing as this is one more way to do what you suggested as well for other users) I did this in my web app's Pom.xml





And in my Ear app's POM.xml added the dependencies of war (your on top of your head was actually right in this case too! nice one there )

So my lib in war/web-inf is empty and the libs are in the root of the ear. I only need to run it on a server to see if it works without any issues. hopefully it will.

I really appreciate your replies, they helped a lot.

Thanks.
Syed...



Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16228
    
  21

Peter Johnson wrote:You don't want to do this.

First, servlets must reside in the WEB-INF/lib directory. (Well, let me say I've never heard of them being outside of it.)

Second, WARs are not transparent, any classes residing in JARs outside of the WAR will not have visibility to classes inside the WAR. This can lead to class not found exceptions.



Actually, most of my servlets are in WEB-INF/classes. The important thing is that the deployed webapp's classpath includes WEB-INF/classes and each and every jar in WEB-INF/lib, but notjars outside of WEB-INF/lib or jars-within-jars. Additional classes (such as JDBC drivers) come from the appserver's application context classpath and the classpath of the appserver itself. What those paths are vary according to vendor and version. In any event, it's generally not a good idea to put application classes in the container classpaths, since they have to be deployed independently of the WAR and may have environmental and/or threading issues.

Like Peter, I do very little with EARS. EARs can contain multiple resources (WARs and EJB Jars, etc/). As I recall, the EAR's application.xml allows the classpath definitions to be established between components, as otherwise the WARs cannot see the EJB jars. Inter-WAR class sharing is not possible because a WAR isn't an executable library JAR, but I believe that the RAR jar can be used to contain such code.

In maven, you would normally have one project to produce each WAR and EJB JAR as separate artifacts. Then an enveloping EAR project would combine them all into a deployable EAR. I wouldn't attempt to use a WAR project to build the EAR directly.


Customer surveys are for companies who didn't pay proper attention to begin with.
Syed Mahdi
Ranch Hand

Joined: Aug 27, 2004
Posts: 45
Thanks Tim,

very nicely explained comments. I appreciate them.

I agree with you guys. I wonder why do I have an EAR project anyway cos in my ear project there are two jars outside as dependent projects for the war (Why are they outside beats me!) When i tried to mavenize the project, maven put these dependent projects as jars into the WEB-INF/lib folder unlike what RSA was doing using the .classpath eclipse file. so now everything is in the war and that lone war is in the ear. it doesn't make sense to me. if its a lonely war why not just deploy it as a web app rather than an enterprise app.

I know you have an enterprise app when you have a web app and EJB jars it make up an ear. but in my case now that i re structured my project through maven and the build comes in as a single war in an ear it doesn't make sense to me. Is there a benefit of making an ear file containing a war file.

I will appreciate if some one can explain me the difference in this case.

I am marking this thread as resolved as my original query of making the libs outside the war is answered.

Thanks
Syed...
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16228
    
  21

Well, for what it's worth, when you deploy a WAR into IBM's WebSphere Application Server (WAS), WAS will construct an EAR and put the WAR inside it. Apparently it comforts WAS to treat all apps as EARs.

In general, however, there's no benefit to an EAR structure unless you do need to bind together artefacts that would otherwise be separate. And, of course, EARs cannot be deployed to Tomcat, so if that's your target server, it's got to be a WAR anyway.
Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5842
    
    7

[quoute]Servlets in lib? I thought they should be in WEB-INF/Classes/
Yeah, I realized that as soon as I hit submit. Goes to show how long it's been since I did a web app. And besides, since Maven does everything for you, who notices such things. But I do recall years ago, in the dark ages before even Ant, JARing up servlets and placing the JAR into WEB-INF/lib. Not sure why I did that, but I did.

When i tried to mavenize the project, maven put these dependent projects as jars into the WEB-INF/lib folder

If you want to prevent the extra JARs from being placed into WEB-INF/lib, mark then with a scope of "provided". Of course then you have to figure what to do with those JARs separately, but often that is what an installation program is for. Or there might be an application-server specific Maven plugin that will do that for you, properly deploying the WAR and any additional JARs.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: maven: the war directory structure