Search code examples
mavenmaven-ear-plugin

Moving From Ant to Maven: How do I setup an EAR Project?


We have a fairly complex project that use to be built in Ant, but now we're moving to Maven.

  1. There is a core jar and a variety of filter jars that depend upon the core jar.
  2. These jars are assembled into a SAR along with other dependent jars and a few XML files. I've called this foo-sar below.
  3. Another JAR is built, but this JAR doesn't contain any Java code, only a few application xml files. I've called this foo-jar below.
  4. The foo-jar and foo-sar are packaged into an EAR with an application.xml file found in the META-INF directory.

I have a Maven project with three sub-projects:

  • foo-jar
  • foo-sar
  • foo-ear

Both foo-jar and foo-sar build just fine. However, when foo-ear builds, it builds the ear with the application.xml file but without foo-jar and foo-sar in it. My directory structure looks like this:

parent Dir --+
             |
             +-- foo-ear
             |
             +-- foo-jar
             |
             +-- foo-sar

The parent directory pom.xml calls all three projects in the correct order (foo-sar, foo-jar, and foo-ear). Both foo-jar and foo-sar build correctly (i.e., I've matched the results of the Ant build). The foo-ear project builds without errors, but it doesn't include the foo-sar and foo-jar files in the root of the ear.

I'm missing something quite simple here. Maybe it's an additional parameter, or another configuration.

Here's the Ear's pom.xml:

<project>
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.vegicorp.foo</groupId>
    <artifactId>foo-parent</artifactId>
    <version>1.0.0</version>
  </parent>
  <groupId>com.vegicorp.foo</groupId>
  <artifactId>foo-app</artifactId>
  <packaging>ear</packaging>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.plugins</groupId>
        <artifactId>maven-ear-plugin</artifactId>
        <version>2.10.1</version>
        <configuration>
          <artifactTypeMappings>
            <!-- The sar is a "jboss-sar" and not just a "sar" -->
            <artifactTypeMapping type="jboss-sar" mapping="sar"/>
          </artifactTypeMappings>
          <modules>
            <jarModule>
              <artifactId>foo-jar</artifactId>
              <unpack>true</unpack>
            </jarModule>
            <sarModule>
              <artifactId>foo-sar</artifactId>
              <unpack>true</unpack>
            </sarModule>
          </modules>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

New Issues

I realized one of the issues I was having is that <groupId> was set to org.apache.plugins and not to org.apache.maven.plugins for the maven-ear-plugin. I have no idea why Maven didn't detect this error before and give me build error before.

Once I set the correct group, I started noticing that the application.xml was being built even though I specified that <generateApplicationXml> was false. I realized this was happening in the generate-application-xml goal, and apparently the default <configuration> is for the ear goal. Thus, I had to specify the <execution> for the generate-application-xml goal and the ear goal separately.

Fun, fun, fun.

I have gotten the ear to generate except for one minor issue, the dependencies in the ear are being downloaded anyway even though I have configured my module information to do things a bit differently. Here's my pom.xml for the Ear:

<project>
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.vegicorp.foo</groupId>
    <artifactId>foo-parent</artifactId>
    <version>1.0.0</version>
  </parent>
  <groupId>com.vegicorp.foo</groupId>
  <artifactId>foo-app</artifactId>
  <packaging>ear</packaging>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-ear-plugin</artifactId>
        <version>2.10.1</version>
        <executions>
          <execution>
            <id>skip-application-xml-generation</id>
            <phase>package</phase>
            <goals>
              <goal>generate-application-xml</goal>
            </goals>
            <configuration>
              <generateApplicationXml>false</generateApplicationXml>
            </configuration>
          </execution>
          <execution>
            <id>create-ear</id>
            <phase>package</phase>
            <goals>
              <goal>ear</goal>
            </goals>
            <configuration>
              <artifactTypeMappings>
                <artifactTypeMapping type="jboss-sar" mapping="sar"/>
              </artifactTypeMappings>
              <modules>
                <jarModule>
                  <groupId>${project.groupId}</groupId>
                  <artifactId>foo-jar</artifactId>
                  <unpack>true</unpack>
                  <uri>FooJar.jar</uri>
                </jarModule>
                <sarModule>
                  <groupId>${project.groupId}</groupId>
                  <artifactId>foo-sar</artifactId>
                  <unpack>true</unpack>
                  <uri>Foo.sar</uri>
                </sarModule>
              </modules>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>foo-sar</artifactId>
      <version>${project.version}</version>
      <type>sar</type>
      <exclusions>
        <exclusion>
          <groupId>*</groupId>
          <artifactId>*</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>foo-jar</artifactId>
      <version>${project.version}</version>
      <exclusions>
        <exclusion>
          <groupId>*</groupId>
          <artifactId>*</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
</project>

And here's the Ear being generated:

$ ls -l foo-app/target/foo-app-1.0.0
drwxr-xr-x    3 david  staff       102 Jan 17 11:21 Foo.jar
drwxr-xr-x  137 david  staff      4658 Jan 17 11:21 Foo.sar
drwxr-xr-x    4 david  staff       136 Jan 17 11:21 META-INF
-rw-r--r--    1 david  staff      3905 Jan 17 11:21 foo-1.0.0.jar
-rw-r--r--    1 david  staff  50104182 Jan 17 11:21 foo-sar-1.0.0.sar

How I can configure my Ear to prevent foo-1.0.0.jar and foo-sar-1.0.0.sar from being included in my Ear? Shouldn't the <module> section of my Ear <configuration> be mapping my dependencies into my modules?


Solution

  • I found a solution. There is probably a much better solution, but this is what I found that works. It's a big, hulking, kludge. Feel free to let me know how wrong I am and the correct way this should be done.

    As arghtype pointed out, I need to add these modules into my dependencies. Doing that works. However, I found it also includes all my dependencies and downloads those into my Ear too. Considering that one of my modules I'm including is a SAR which contains its own massive number of jar dependencies, that was just silly.

    To eliminate the dependencies, I originally tried <exclusions> in the dependency description, but that didn't get rid of the added jar and sar. What I finally did was put a <scope>provided</scope> in my pom.xml to prevent these from downloading.

    This works, but there must be a better way of doing this:

    <project>
      <modelVersion>4.0.0</modelVersion>
    
      <parent>
        <groupId>com.vegicorp.foo</groupId>
        <artifactId>foo-parent</artifactId>
        <version>1.0.0</version>
      </parent>
      <groupId>com.vegicorp.foo</groupId>
      <artifactId>foo-app</artifactId>
      <packaging>ear</packaging>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <version>2.10.1</version>
            <executions>
              <execution>
                <id>skip-application-xml-generation</id>
                <phase>package</phase>
                <goals>
                  <goal>generate-application-xml</goal>
                </goals>
                <configuration>
                  <generateApplicationXml>false</generateApplicationXml>
                </configuration>
              </execution>
              <execution>
                <id>create-ear</id>
                <phase>package</phase>
                <goals>
                  <goal>ear</goal>
                </goals>
                <configuration>
                  <artifactTypeMappings>
                    <artifactTypeMapping type="jboss-sar" mapping="sar"/>
                  </artifactTypeMappings>
                  <modules>
                    <jarModule>
                      <groupId>${project.groupId}</groupId>
                      <artifactId>foo-jar</artifactId>
                      <unpack>true</unpack>
                      <uri>FooJar.jar</uri>
                    </jarModule>
                    <sarModule>
                      <groupId>${project.groupId}</groupId>
                      <artifactId>foo-sar</artifactId>
                      <unpack>true</unpack>
                      <uri>Foo.sar</uri>
                    </sarModule>
                  </modules>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      <dependencies>
        <dependency>
          <groupId>${project.groupId}</groupId>
          <artifactId>foo-sar</artifactId>
          <version>${project.version}</version>
          <type>sar</type>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>${project.groupId}</groupId>
          <artifactId>foo-jar</artifactId>
          <version>${project.version}</version>
          <scope>provided</scope>
        </dependency>
      </dependencies>
    </project>