tags:

views:

743

answers:

2

Situation is pretty straightforward. I have a Java webapp that I'm converting to be built with Maven. At present, the app is built with Ant into a single WAR file, which is then bundled into an EAR with a very simple application.xml.

maven-war-plugin and maven-ear-plugin both look pretty straightforward to me, and it appears they're setting me up to be forced to consider the above as two distinct projects, with the WAR project as a dependency of the EAR project. This seems a tad inconvenient, especially because a profile setting of the WAR project will change for each environment, which seems like it would force me to duplicate that build tweaking each time I attempted to build the EAR as well.

All of that to say: is there a straightforward way to build the WAR and package that into this trivially-simple EAR? I'd like to avoid maintaining these as two separate projects, but would similarly prefer not to resort to an overly messy hack using assemblies to accomplish this.

+7  A: 

All of that to say: is there a straightforward way to build the WAR and package that into this trivially-simple EAR? I'd like to avoid maintaining these as two separate projects, but would similarly prefer not to resort to an overly messy hack using assemblies to accomplish this.

Short answer: no, there is no simple maven-way to do that as this would go against a Maven rule which is "one artifact per project" (understand one output per project which is true in 99% of the cases).

And actually, I would strongly recommend to not go the hacky way and forget using assemblies to create an EAR. Instead, create two modules, one with a packaging of type war, the other with a packaging of type ear depending on the war artifact and declare them as modules of a parent pom.xml. Like this:

my-project
|-- pom.xml       // packaging of type pom and my-war and my-ear as modules
|-- my-war
|   `-- pom.xml   // packaging of type war
`-- my-ear
    `-- pom.xml   // packaging of type ear

If you go for Maven, adopt Maven philosophy, don't fight against it, it will save you lot of pain. Seriously, hacking assemblies to do what the maven-ear-plugin is already doing is just anti DRY. You'd better stick to Ant in that case.

Pascal Thivent
+1 - don't fight maven
Stephen C
For what it's worth, I wasn't advocating taking a hacky approach/fighting Maven, I simply sensed that there was no other outlet short of creating multiple projects/modules. I only posed the question on SO to confirm that there was in fact no clean way of accomplishing this within a single project. As such, I'll plan go with the layout you outlined above.
Justin Searls
A: 

In Maven every single project produce an aritifact. In your situation I suggest create two project one for war and one for ear. If you need mutltiple versions of your projects you can achive that using classifiers and profiles.

This is excerpt of richfaces examples pom.

    <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <executions>
          <execution>
            <id>jee5</id>
            <phase>package</phase>
            <goals>
              <goal>war</goal>
            </goals>
            <configuration>
              <webappDirectory>${project.build.directory}/${project.build.finalName}-jee5</webappDirectory>
              <classifier>jee5</classifier>
              <packagingExcludes>WEB-INF/lib/jsf-api*,WEB-INF/lib/jsf-impl*,WEB-INF/lib/el-*</packagingExcludes>
     <warSourceExcludes>WEB-INF/lib/jsf-api*,WEB-INF/lib/jsf-impl*,WEB-INF/lib/el-*</warSourceExcludes>
            </configuration>
          </execution>
          <execution>
            <id>tomcat6</id>
            <phase>package</phase>
            <goals>
              <goal>war</goal>
            </goals>
            <configuration>
              <webappDirectory>${project.build.directory}/${project.build.finalName}-tomcat6</webappDirectory>
              <classifier>tomcat6</classifier>
     <packagingExcludes>WEB-INF/lib/el-*</packagingExcludes>
     <warSourceExcludes>WEB-INF/lib/el-*</warSourceExcludes>
            </configuration>
          </execution>
        </executions>
        <configuration>
          <webResources>
            <resource>
              <directory>${basedir}/src/main/java</directory>
              <targetPath>/WEB-INF/src</targetPath>
            </resource>
          </webResources>
        </configuration>
      </plugin>

In your ear pom use profiles to import required dependency with appropriate classifier.

<profile>
  <id>jee5</id>
  <dependencies>
     <dependency>
       <groupId>org.richfaces.samples</groupId>
       <artifactId>richfaces-demo</artifactId>
       <version>${richfaces-version}</version>
       <classifier>jee5</classifier>
       <type>war</type>
       <scope>runtime</scope>
     </dependency>
  </dependencies>
</profile>
cetnar