Sometimes you write a blog to express an idea, to ask some feedback from the community, to share a very nice trick… or because you always forget something and want to write it down so you can remember later on. That’s the reason of this post. I never remember how to use the maven-ear-plugin, so I’m writing it down. There is something funny with Maven and I. I spend hours trying to figure out to do something with Maven, and then, I automatically forget it. That’s the beauty of human’s brain : it doesn’t hold junk information for long.
Let’s say you have a project made of a Web module, an EJB module and external Lucene libraries. You then need to package this entire application into a ear file plus a few configuration files (login-config.xml and the application.xml deployment descriptor). With Maven each module is defined into a separate directory with its own pom.xml. So you will end up with the following structure :
- a root pom.xml
- a web module with its own pom.xml
- an EJB module with its own pom.xml
- an ear module that will be used only to package the entire application
I will not define what’s in the pom.xml of the web and EJB module, but only the interesting part : the pom.xml of the ear module, that’s where you define the maven-ear-plugin :
- The first part of the pom.xml is quite normal, nothing special except the packaging that is set to ear (<packaging>ear<packaging>).
- Then you have the dependencies. Here you define the web and EJB modules as well as the Lucene libraries. Note that it’s very important to specify <type>war</type> for the web module. If you don’t Maven will look for a jar file.
- Then comes the definition and configuration of the maven-ear-plugin. Notice that I redefine the artifacts that depend on the application but I add the extra information of the module : <webModule>, <ejbModule> or <jarModule>. Also note that I’ve decided to package the Lucene libraries into a subdirectory called lucenelib.
[sourcecode language=”xml”]
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.example.mvnearplg</groupId>
<artifactId>ear</artifactId>
<packaging>ear</packaging>
<version>1.0</version>
<parent>
<groupId>org.example</groupId>
<artifactId>mvnearplg</artifactId>
<version>1.0</version>
</parent>
<dependencies>
<!– web and ejb modules –>
<dependency>
<groupId>org.example.mvnearplg</groupId>
<artifactId>ejb</artifactId>
<version>1.0</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>org.example.mvnearplg</groupId>
<artifactId>web</artifactId>
<version>1.0</version>
<type>war</type>
</dependency>
<!– external lucene libraries –>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.3.2</version>
<!– configuring the ear plugin –>
<configuration>
<modules>
<webModule>
<groupId>org.example.mvnearplg</groupId>
<artifactId>web</artifactId>
</webModule>
<ejbModule>
<groupId>org.example.mvnearplg</groupId>
<artifactId>ejb</artifactId>
</ejbModule>
<!–extra lucene libs into lucenelib directory –>
<jarModule>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<bundleDir>lucenlib</bundleDir>
</jarModule>
<jarModule>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<bundleDir>lucenelib</bundleDir>
</jarModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
</project>
[/sourcecode]
The ear plugin looks for its resources under the src/main/application directory. That’s where you typically put your META-INF directory with the application.xml file and some extra descriptors. So the result is that :
- The external Lucene libraries are under the lucenelib directory (that’s because I’ve specified the <bundleDir>, otherwise they would have been under the root directory)
- The META-INF/application.xml and the /login-config.xml files are automatically packaged in the ear file (that’s because they were under the default resource directory src/main/application).
- The ejb module (ejb-1.0.jar) and web module (web-1.0.war) are located under the root directory
Next time I’ll need the ear plugin I’ll remember to read my own post.
Thank you for your article.
I have a question about the application.xml file :
what do we must put in this file ?
I mean : does maven inform the modules declarations ? Or do we must declare modules ourselves
If you have a Java EE 5 application, the application.xml is optional. Otherwise, the maven-ear-plugin has a goal to create an application.xml file (mvn ear:generate-application-xml )
Great post! This was really helpful.
what about the parent? is it a multi-module project? i am trying to figure how a multi-module relates to an ear project.
i figured out ok. it’s the multi-module. i just hoped i didn’t had to have TWO empty projects (multi-module, EAR) to make it work.
Hi Antonio,
Your post should definitely go into the plugin’s usage page!
I’m not new to Maven, but having switched from EJB + JBoss to Spring and Tomcat long ago, I do no longer remember how to build ears 🙂 I’m now being forced to deploy a war to JBoss and thus trying to solve those dreaded class loader problems.
Looking at your single page post, within seconds I knew what the ear-plugin is all about – the Maven site does not even mention the fact that the maven-ear-plugin will use the dependencies from the pom.xml to gather the wars etc.
Thanks again, great work,
Reiner
Tx! Very useful post.
Transaction? 😀
Very good article.
I have a question tho. i have a parent pom called ebusiness, war module called eagent and an ear project. All my dependencies are at the root pom.xml level. When i add the war dependency to ear pom.xml using maven ear plugin i see at the root level creation of the ear all my jar files and eagent. war. I only want to see eagent.war as the jars are bundled inside.
So my questioin is how can i exclude the other dependencies from root ear level?
Ear pom.xml
4.0.0
au.gov.asic
EbusEAR01
0.0.1-SNAPSHOT
ear
EbusEAR01
Deploying war in an ear
au.gov.asic
ebusiness
1.4-SNAPSHOT
../ebusiness/pom.xml
EbusEAR01-${project.version}
maven-ear-plugin
2.4.1
true
jar
true
**/*.jar
au.gov.asic
eagent
<!– true –>
<!– /lt-web –>
au.gov.asic
eagent
war
1.4-SNAPSHOT
Regards,
Shane.
Hi Shane,
try declaring the dependency to eagent as provided. I know it looks strange, but that’s what worked for me in a similar case.
Regards,
Reiner
Thanks for sharing – this post was really helpful to me learning about using Maven to build projects as EARs.
Genial. Gracias.
It helps me a lot.
Very good post!!! Thanks!!
I have a question… All dependencie inside ear.pom.xml (org.example.mvnearplg,org.example.mvnearplg) should be in my local repository for maven do build?
thanks a lot!
Antonio,
you don’t need to define webModule and ejbModule in your ear plugin configuration. By convention, all ear dependencies will be deployed in the resulting .ear (wars and ejbs under the /, using the default artifact file name, jars under the default bundle dir (/ ,if you haven’t set it to lib/)
I generally only configure the webModule’s contextRoot (ex. /web), since by default it’d be /web-X.Y.Z-(SNAPSHOT)
regards,
Fred (m2eclipse-wtp guy)
Why not show the content in all pom.xml files?
Thank you for posting this. Even after so long, it still answered many questions I had a bout doing this. Applying your ideas to a partially complete ear build, got it going.
j
Great article!
When you execute package under the ear project maven tries to look for the dependencies in the repository.Maven does not know where to find the ejb dependencies other than looking into the repository. Is this a bug? How do you actually build the ear?
My SO Question: http://stackoverflow.com/questions/9700735/maven-ear-plugin-could-not-resolve-dependencies-to-ejbmodule
Hi antonio,
When i added to my pom.xml for multimodule project, i go the following error in building the project.
Prior to adding this, it was working fine. I wanted to add all my dependencies into APP-INF folder using .
Please Help.
ReFormEAR
reform
com.pg.giss
3.0.0-SNAPSHOT
4.0.0
com.pg.giss
ReFormEAR
ear
${project.parent.version}
ReFormEAR
org.apache.maven.plugins
maven-ear-plugin
2.3.2
com.pg.giss
ReForm-webapp
ReForm.war
ReForm.war
/ReForm
com.pg.giss
ReForm-ejb
ejbGiss.jar
javax.ejb
ejb-api
${ejb-api.version}
APP-INF/lib
false
log4j
log4j
1.2.16
APP-INF/lib
false
addign pom.xml again for reference
ReFormEAR
reform
com.pg.giss
3.0.0-SNAPSHOT
4.0.0
com.pg.giss
ReFormEAR
ear
${project.parent.version}
ReFormEAR
org.apache.maven.plugins
maven-ear-plugin
2.3.2
com.pg.giss
ReForm-webapp
ReForm.war
ReForm.war
/ReForm
com.pg.giss
ReForm-ejb
ejbGiss.jar
javax.ejb
ejb-api
${ejb-api.version}
APP-INF/lib
false
log4j
log4j
1.2.16
APP-INF/lib
false
com.pg.giss
ReForm-webapp
${project.parent.version}
war
com.pg.giss
ReForm-ejb
${project.parent.version}
ejb
sorry, i was adding in
i got my mistake.
Thanks
Thank you very much buddy was able to do it in minutes
And do you have any thing specific to weblogic or websphere?
Thx for article – it helped me to build example for JBoss AS7 with Spring: https://github.com/hamsterready/jboss-as7-singleton-using-spring
Hi having a doubt regarding the assembly of ear . The ear-plugin hs been properly used in the project I two queries . The application.xml is not present in the src/main/application/META-INF/ . Just MANIFEST.MF is there .
But once the I compile the project this file is created .
second thing is that though the compilation got successful if I try to run mvn -e install it does not copies the ear to local repository and build failes with
Failed to retrieve numeric file attributes using: ‘/bin/sh -c ls -1nlad
Please advise
Good post. Thank you.
I have the same kind of modules and I was using ant. I’m new to maven and looking for maven ear plugin. My directory structure is:
|
|-EARModule
|-EARContent
|-WEB-INF
|
|-WebModule
|—-
|
|-Sheduler
|—
so, ear module directory structure is different. I’m using java 1.6. I used downloaded jar files in lib directory(web module). I want to create ear file using maven. how do I write parent pom.xml and others. Can someone help me?
under ear module, it is containing EARContent and inside EARContent directory WEB-INF there.
Hi,
Thanks for the post. I have created 3 projects based on the packaging that is currently happening through ant. 1 for JAR and 2 for war files. I defined the pom.xml in the same way as u mentioned above. But when i try to run maven build on the pom.xml of the ear project it fails with the following error :
Could not resolve dependencies for projEar:projEar:ear.
is it required to build the ejb and web projects before hand and then add them as a dependency ?
I am not sur e about the issue :
When i try to deploy i got this error ,
[-2018e1-ass-bass] /opt/ss/jboss-eap-6.4/standalone/deployments # cat dis-cre-ear-2.0.4-SNAPSHOT.ear.failed
{“JBAS014653: Composite operation failed and was rolled back. Steps that failed:” => {“Operation step-2” => {“JBAS014671: Failed services” => {
“jboss.module.service.\”deployment.dis-cre-ear-2.0.4-SNAPSHOT.ear\”.main” => “org.jboss.msc.service.StartException in service jboss.module.service.\”deployment.dis-cre-ear-2.0.4-SNAPSHOT.ear\”.main: JBAS018759: Failed to load module: deployment.dis-cre-ear-2.0.4-SNAPSHOT.ear:main
Caused by: org.jboss.modules.ModuleNotFoundException: com.sopra.configuration:main”,
“jboss.module.service.\”deployment.dis-cre-ear-2.0.4-SNAPSHOT.ear.dis-cre-rm-ejb-2.0.4-SNAPSHOT.jar\”.main” => “org.jboss.msc.service.StartException in service jboss.module.service.\”deployment.dis-cre-ear-2.0.4-SNAPSHOT.ear.dis-cre-rm-ejb-2.0.4-SNAPSHOT.jar\”.main: JBAS018759: Failed to load module: deployment.dis-cre-ear-2.0.4-SNAPSHOT.ear.dis-cre-rm-ejb-2.0.4-SNAPSHOT.jar:main
Caused by: org.jboss.modules.ModuleNotFoundException: com.sopra.configuration:main”
}}}}[-2018e1-ass-bass] /opt/ss/jboss-eap-6.4/standalone/deployments # dis-cre-ear-2.0.4-SNAPSHOT.ear.failed
ksh: dis-cre-ear-2.0.4-SNAPSHOT.ear.failed: not found [No such file or directory]
[-2018e1-ass-bass] /opt/ss/jboss-eap-6.4/standalone/deployments #