Because I always forget how to use maven-ear-plugin

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
maven-ear

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

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

maven-ear-done

Next time I’ll need the ear plugin I’ll remember to read my own post.

Categories: Java

Tagged as:

26 Comments »

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

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

  3. what about the parent? is it a multi-module project? i am trying to figure how a multi-module relates to an ear project.

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

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

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

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

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

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

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

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

  12. Thank you very much buddy was able to do it in minutes
    And do you have any thing specific to weblogic or websphere?

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

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

  15. 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 ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s