【问题标题】:Maven2: Best practice for Enterprise Project (EAR file)Maven2:企业项目的最佳实践(EAR 文件)
【发布时间】:2010-11-11 05:12:47
【问题描述】:

我刚刚从 Ant 切换到 Maven,并试图找出设置基于 EAR 文件的企业项目的最佳实践?

假设我想创建一个非常标准的项目,其中包含一个用于 EJB 的 jar 文件、一个用于 Web 层的 WAR 文件和一个封装的 EAR 文件,以及相应的部署描述符。

我会怎么做呢?使用archetypeArtifactId=maven-archetype-webapp 像使用war 文件一样创建项目,然后从那里扩展?什么是最好的项目结构(和 POM 文件示例)?你把ear文件相关的部署描述符等放在哪里?

感谢您的帮助。

【问题讨论】:

    标签: jakarta-ee maven-2 ear maven-ear-plugin


    【解决方案1】:

    您创建了一个新项目。新项目是您的 EAR 组装项目,其中包含 EJB 项目和 WAR 项目的两个依赖项。

    所以你实际上在这里有三个 maven 项目。一个 EJB。一场战争。一个 EAR 将两个部分拉在一起并形成耳朵。

    部署描述符可以由 maven 生成,也可以放在 EAR 项目结构的资源目录中。

    maven-ear-plugin 是您用来配置它的工具,the documentation 很好,但如果您仍在弄清楚 maven 的总体工作原理,还不太清楚。

    所以作为一个例子,你可能会做这样的事情:

    <?xml version="1.0" encoding="utf-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.mycompany</groupId>
      <artifactId>myEar</artifactId>
      <packaging>ear</packaging>
      <name>My EAR</name>
    
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.5</source>
              <target>1.5</target>
              <encoding>UTF-8</encoding>
            </configuration>
          </plugin>
          <plugin>
            <artifactId>maven-ear-plugin</artifactId>
            <configuration>
              <version>1.4</version>
              <modules>
                <webModule>
                  <groupId>com.mycompany</groupId>
                  <artifactId>myWar</artifactId>
                  <bundleFileName>myWarNameInTheEar.war</bundleFileName>
                  <contextRoot>/myWarConext</contextRoot>
                </webModule>
                <ejbModule>
                  <groupId>com.mycompany</groupId>
                  <artifactId>myEjb</artifactId>
                  <bundleFileName>myEjbNameInTheEar.jar</bundleFileName>
                </ejbModule>
              </modules>
              <displayName>My Ear Name displayed in the App Server</displayName>
              <!-- If I want maven to generate the application.xml, set this to true -->
              <generateApplicationXml>true</generateApplicationXml>
            </configuration>
          </plugin>
          <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.3</version>
            <configuration>
              <encoding>UTF-8</encoding>
            </configuration>
          </plugin>
        </plugins>
        <finalName>myEarName</finalName>
      </build>
    
      <!-- Define the versions of your ear components here -->
      <dependencies>
        <dependency>
          <groupId>com.mycompany</groupId>
          <artifactId>myWar</artifactId>
          <version>1.0-SNAPSHOT</version>
          <type>war</type>
        </dependency>
        <dependency>
          <groupId>com.mycompany</groupId>
          <artifactId>myEjb</artifactId>
          <version>1.0-SNAPSHOT</version>
          <type>ejb</type>
        </dependency>
      </dependencies>
    </project>
    

    【讨论】:

    • 一年后,当我遇到同样的问题时,我找到了自己的答案。干得好!
    • 当我将 type 设置为 ejb &lt;type&gt;ejb&lt;/type&gt; 时,这对我来说有效
    • 那个 pom 会抛出一些警告:'build.plugins.plugin.version' for org.apache.maven.plugins:maven-ear-plugin is missing'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing,所以你可能想要更新你原本很好的答案
    【解决方案2】:

    对我帮助很大的是运行 Maven 原型:生成目标并从其中一个原型中进行选择,其中一些似乎定期更新(特别是 JBoss 似乎维护得很好)。

    mvn archetype:generate
    

    数百个原型出现在一个可供选择的编号列表中(截至目前为 519 个!)。仍在运行的目标提示我通过输入数字或输入搜索字符串进行选择,例如:

    513: remote -> org.xwiki.commons:xwiki-commons-component-archetype
    514: remote -> org.xwiki.rendering:xwiki-rendering-archetype-macro
    515: remote -> org.zkoss:zk-archetype-component
    516: remote -> org.zkoss:zk-archetype-webapp
    517: remote -> ru.circumflex:circumflex-archetype (-)
    518: remote -> se.vgregion.javg.maven.archetypes:javg-minimal-archetype (-)
    Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains):
    

    我输入了搜索字符串“ear”,这使列表减少到只有 8 个项目(截至今天):

    Choose archetype:
    1: remote -> org.codehaus.mojo.archetypes:ear-j2ee14 (-)
    2: remote -> org.codehaus.mojo.archetypes:ear-javaee6 (-)
    3: remote -> org.codehaus.mojo.archetypes:ear-jee5 (-)
    4: remote -> org.hibernate:hibernate-search-quickstart (-)
    5: remote -> org.jboss.spec.archetypes:jboss-javaee6-ear-webapp 
    6: remote -> org.jboss.spec.archetypes:jboss-javaee6-webapp-ear-archetype
    7: remote -> org.jboss.spec.archetypes:jboss-javaee6-webapp-ear-archetype-blank
    8: remote -> org.ow2.weblab.tools.maven:weblab-archetype-searcher
    

    我选择了“org.jboss.spec.archetypes:jboss-javaee6-ear-webapp”(在本例中输入选择“5”)。

    接下来,目标要求我输入 groupId、artifactId、包名等,然后它生成了以下文档齐全的示例应用程序:

    [pgarner@localhost Foo]$ tree
    .
    |-- Foo-ear
    |   `-- pom.xml
    |-- Foo-ejb
    |   |-- pom.xml
    |   `-- src
    |       |-- main
    |       |   |-- java
    |       |   |   `-- com
    |       |   |       `-- foo
    |       |   |           |-- controller
    |       |   |           |   `-- MemberRegistration.java
    |       |   |           |-- data
    |       |   |           |   `-- MemberListProducer.java
    |       |   |           |-- model
    |       |   |           |   `-- Member.java
    |       |   |           `-- util
    |       |   |               `-- Resources.java
    |       |   `-- resources
    |       |       |-- import.sql
    |       |       `-- META-INF
    |       |           |-- beans.xml
    |       |           `-- persistence.xml
    |       `-- test
    |           |-- java
    |           |   `-- com
    |           |       `-- foo
    |           |           `-- test
    |           |               `-- MemberRegistrationTest.java
    |           `-- resources
    |-- Foo-web
    |   |-- pom.xml
    |   `-- src
    |       `-- main
    |           |-- java
    |           |   `-- com
    |           |       `-- foo
    |           |           `-- rest
    |           |               |-- JaxRsActivator.java
    |           |               `-- MemberResourceRESTService.java
    |           `-- webapp
    |               |-- index.html
    |               |-- index.xhtml
    |               |-- resources
    |               |   |-- css
    |               |   |   `-- screen.css
    |               |   `-- gfx
    |               |       |-- banner.png
    |               |       `-- logo.png
    |               `-- WEB-INF
    |                   |-- beans.xml
    |                   |-- faces-config.xml
    |                   `-- templates
    |                       `-- default.xhtml
    |-- pom.xml
    `-- README.md
    
    32 directories, 23 files
    

    在阅读了四个评论很好的 POM 文件后,我几乎掌握了我需要的所有信息。

    ./pom.xml
    ./Foo-ear/pom.xml
    ./Foo-ejb/pom.xml
    ./Foo-web/pom.xml
    

    【讨论】:

    • 这行得通,但它最终会将一堆特定于 jboss 的依赖项放入您的项目中,您可能想也可能不想在事后清理它们。
    【解决方案3】:

    我已经创建了一个 github 存储库来展示我认为好的(或最佳实践)启动项目结构...

    https://github.com/StefanHeimberg/stackoverflow-1134894

    一些关键字:

    • Maven 3
    • BOM(自身依赖的依赖管理)
    • 所有项目的父项(来自外部依赖项的 DependencyManagement 和用于全局项目配置的 PluginManagement)
    • JUnit / Mockito / DBUnit
    • 没有 WEB-INF/lib 的 Clean War 项目,因为依赖项位于 EAR/lib 文件夹中。
    • 清洁耳朵项目。
    • Java EE7 的最小部署描述符
    • 没有本地 EJB 接口,因为 @LocalBean 就足够了。
    • 通过 maven 用户属性进行最小化 maven 配置
    • Servlet 3.1 / EJB 3.2 / JPA 2.1 的实际部署描述符
    • 使用 macker-maven-plugin 检查架构规则
    • 集成测试已启用,但已跳过。 (skipITs=false) 在 CI 构建服务器上启用很有用

    Maven 输出:

    Reactor Summary:
    
    MyProject - BOM .................................... SUCCESS [  0.494 s]
    MyProject - Parent ................................. SUCCESS [  0.330 s]
    MyProject - Common ................................. SUCCESS [  3.498 s]
    MyProject - Persistence ............................ SUCCESS [  1.045 s]
    MyProject - Business ............................... SUCCESS [  1.233 s]
    MyProject - Web .................................... SUCCESS [  1.330 s]
    MyProject - Application ............................ SUCCESS [  0.679 s]
    ------------------------------------------------------------------------
    BUILD SUCCESS
    ------------------------------------------------------------------------
    Total time: 8.817 s
    Finished at: 2015-01-27T00:51:59+01:00
    Final Memory: 24M/207M
    ------------------------------------------------------------------------
    

    【讨论】:

    • 我真的很喜欢你的包装和架构方法。您应该考虑将您的项目打包为 maven 原型。
    • 非常好的解决方案!不过我有一个问题:为什么不将 BOM 的东西打包到父项目中呢?为什么要增加一层?
    • 关注点分离的原因。 bom 可以由其他项目导入。他们只需要您的依赖项的dependencyManagement,而不需要您正在使用的依赖项的dependencyManagement。好的。你可以说,如果没有人使用你的项目,这个额外的层是不必要的..但​​我认为它也很有意义......可读性。父项目的dependencyManagement 没有与您的依赖项混合......在一个具有> 50 个内部maven 项目的更大项目中,父项目中的dependencyManagement 可能是一团糟..
    • 另一个原因是这与maven.apache.org/guides/introduction/… 中记录的结构相同。这有助于在团队成员经常变化的团队中工作,因为这是“默认”的记录方式。
    • 顺便说一句。我曾经创建了一个 GitHub 项目来展示如何进行多项目设置:github.com/StefanHeimberg/maven3-multiapplication-setup(用于公司内部讨论)
    【解决方案4】:

    NetBeans IDE 自动定义了与 Patrick Garner 建议的结构几乎相似的结构。对于 NetBeans 用户

    文件->新建项目 ->在左侧选择Maven,在右侧选择Maven Enterprise Application 然后按 Next -> 询问 war、ejb 和设置的项目名称。

    IDE 会自动为您创建结构。

    【讨论】:

    • 我同意你的观点,特别是在遵守 JEE6 规范时
    【解决方案5】:

    这是a good example of the maven-ear-plugin 部分。

    您还可以查看maven archetypes 作为示例。如果您只是运行 mvn archetype:generate,您将获得可用原型的列表。其中之一是

    maven-archetype-j2ee-simple
    

    【讨论】:

    • maven-archetype-j2ee-simple 在结构上似乎不必要地复杂——尤其是模块内部的模块,以及用于日志记录之类的单独模块。我不明白这种结构背后的基本原理
    【解决方案6】:

    我一直在寻找一个完整的基于 maven 的耳包应用程序的端到端示例,最后偶然发现了this。说明说通过 CLI 运行时选择选项 2,但出于您的目的,请使用选项 1。

    【讨论】:

    • 链接抛出未经授权的错误。这就是编写完整解决方案而不是依赖链接的原因。
    猜你喜欢
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    相关资源
    最近更新 更多