In Maven2, what's the simplest way to build a WAR and the EAR to contain that WAR in a single POM?

会有一股神秘感。 提交于 2019-12-03 01:13:48

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.

I know this is 5 years old now, but it was still the first answer that came up when I searched. Also, whilst "that's not the maven way" is a perfectly reasonable answer for some people, others may still prefer to use a single pom as the OP asked, and it is really not that complicated.

First, create a standard war pom.xml to generate the war file you want to include in the ear. Leave the packaging as war.

Then write your own application.xml (in src/main/application or wherever) using a placeholder for the war file name:

<application xmlns="http://java.sun.com/xml/ns/javaee" ... >
  <module>
    <web>
      <web-uri>${project.build.finalName}.war</web-uri>
      <context-root>myapp</context-root>
    </web>
  </module>
</application>

And include any other server-specific xml files (weblogic-application.xml etc.) in the same location.

Next, add a resources section to replace the placeholder with the war file name:

<resources>
  <resource>
    <directory>src/main/application</directory>
    <filtering>true</filtering>
    <includes>
      <include>META-INF/*.xml</include>
    </includes>
  </resource>
</resources>

Finally, add an ant ear task to built the ear:

<plugin>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>run</goal>
      </goals>
      <configuration>
        <tasks>
          <ear destfile="${project.build.directory}/${project.build.finalName}.ear"
               appxml="${project.build.outputDirectory}/META-INF/application.xml">
            <fileset dir="${project.build.outputDirectory}" includes="META-INF/*.xml"/>
            <fileset dir="${project.build.directory}" includes="${project.build.finalName}.war"/>
          </ear>
        </tasks>
      </configuration>
    </execution>
  </executions>
</plugin>

And that's it.

cetnar

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>   
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!