在Maven2中,构建WAR和EAR以在单个POM中包含该WAR的最简单方法是什么?

时间:2009-12-08 22:00:35

标签: java maven-2 pom.xml maven-war-plugin maven-ear-plugin

情况非常简单。我有一个Java webapp,我正在转换为使用Maven构建。目前,应用程序使用Ant构建到单个WAR文件中,然后使用非常简单的application.xml将其捆绑到EAR中。

maven-war-pluginmaven-ear-plugin对我来说都非常简单,看起来他们让我把上述视为两个不同的项目,将WAR项目视为依赖项EAR项目。这似乎有点不方便,特别是因为WAR项目的配置文件设置会因每个环境而改变,这似乎会强迫我每次尝试构建EAR时都会复制该构建调整。

所有这些都说:是否有一种简单的方法来构建WAR并将其打包到这个简单易用的EAR中?我想避免将这些项目作为两个单独的项目进行维护,但同样也不愿意使用程序集来实现这一目标。

3 个答案:

答案 0 :(得分:17)

  

所有这些都说:是否有一种简单的方法来构建WAR并将其打包到这个简单易用的EAR中?我想避免将这些项目作为两个单独的项目进行维护,但同样也不愿意使用程序集来实现这一目标。

简短回答:没有,没有简单的maven方法可以做到这一点,因为这会违反Maven规则,即“每个项目一个工件”(了解每个项目的一个输出是真的在99%的情况下)。

实际上,我强烈建议采用hacky方式并忘记使用程序集来创建EAR。相反,创建两个模块,一个包含类型为war的包装,另一个包含类型为ear的包装,具体取决于war工件,并将它们声明为父pom.xml的模块。像这样:

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

如果你选择Maven,采用Maven哲学,不要反对它,它将为你节省很多痛苦。说真的,黑客组装来做maven-ear-plugin已经做的事情只是反DRY。在这种情况下你最好坚持使用Ant。

答案 1 :(得分:2)

在Maven中,每个项目都会产生一个aritifact。在你的情况下,我建议创建两个项目一个用于战争,一个用于耳朵。如果您需要多个版本的项目,您可以使用分类器和配置文件来实现。

这是richfaces例子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>

在您的耳中,使用配置文件通过适当的分类器导入所需的依赖关系。

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

答案 2 :(得分:2)

我知道现在已经5岁了,但这仍然是我搜索时出现的第一个答案。此外,虽然&#34;这不是maven方式&#34;对于某些人来说,这是一个非常合理的答案,其他人可能仍然喜欢使用单个pom,就像OP所说的那样,而且实际上并没有那么复杂。

首先,创建一个标准的war pom.xml来生成要包含在耳中的war文件。把包装当作战争。

然后使用warholder文件名的占位符编写自己的application.xml(在src / main / application或wherever中):

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

并在同一位置包含任何其他特定于服务器的xml文件(weblogic-application.xml等)。

接下来,添加资源部分以使用war文件名替换占位符:

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

最后,添加一个蚂蚁耳朵任务来构建耳朵:

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

就是这样。