查找多模块maven reactor项目的根目录

Chr*_*röm 64 directory maven-2 module root

我想使用maven-dependency-plugin将我的多模块项目的所有子模块中的EAR文件复制到相对于整个项目的根目录的目录.

也就是说,我的布局看起来与此类似,名称已更改:

to-deploy/
my-project/
    ear-module-a/
    ear-module-b/
    more-modules-1/
        ear-module-c/
        ear-module-d/
    more-modules-2/
        ear-module-e/
        ear-module-f/
    ...
Run Code Online (Sandbox Code Playgroud)

我希望所有的EAR文件都从它们各自模块的目标目录中复制到my-project/../to-deploy最后

to-deploy/
    ear-module-a.ear
    ear-module-b.ear
    ear-module-c.ear
    ear-module-d.ear
    ear-module-e.ear
    ear-module-f.ear
my-project/
    ...
Run Code Online (Sandbox Code Playgroud)

我可以在每个耳模块中使用相对路径来完成它,如下所示:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>install</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>${project.groupId}</groupId>
                                <artifactId>${project.artifactId}</artifactId>
                                <version>${project.version}</version>
                                <type>ear</type>
                                <outputDirectory>../../to-deploy</outputDirectory>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
Run Code Online (Sandbox Code Playgroud)

但我宁愿不在<outputDirectory>元素中指定相对路径.我更喜欢类似的东西${reactor.root.directory}/../to-deploy,但我找不到这样的东西.

此外,我更喜欢有一些方法来继承这个maven-dependency-plugin配置,所以我不必为每个EAR模块指定它.

我还尝试从根pom继承自定义属性:

<properties>
    <myproject.root>${basedir}</myproject.root>
</properties>
Run Code Online (Sandbox Code Playgroud)

但是当我试图${myproject.root}在耳模块POM中使用时,${basedir}它将解析为耳模块的基础.

另外,我找到了http://labs.consol.de/lang/de/blog/maven/project-root-path-in-a-maven-multi-module-project/,其中建议每个开发人员,大概是连续的集成服务器应该在profiles.xml文件中配置根目录,但我不认为它是一个解决方案.

那么有一种简单的方法可以找到多模块项目的根目录吗?

小智 70

使用 ${session.executionRootDirectory}

为了记录,${session.executionRootDirectory}我在Maven 3.0.3中的pom文件中工作.该属性将是您正在运行的目录,因此运行父项目,每个模块都可以获取该根目录的路径.

我在父pom中使用了这个属性的插件配置,以便继承它.我在一个配置文件中使用它,我只选择当我知道我将在父项目上运行Maven时.这样,当我在子项目上运行Maven时,我不太可能以不希望的方式使用这个变量(因为那时变量不是父项的路径).

例如,

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-artifact</id>
            <phase>package</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>${project.artifactId}</artifactId>
                        <version>${project.version}</version>
                        <type>${project.packaging}</type>
                    </artifactItem>
                </artifactItems>
                <outputDirectory>${session.executionRootDirectory}/target/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)

  • 我用Maven 3.3.9尝试了$ {session.executionRootDirectory},它不再起作用了.您需要使用$ {user.dir}.在我看来,这个选项并不令人满意,因为这意味着我只能独立运行父模块而不是子模块.要做到这一点,你需要这个http://stackoverflow.com/questions/1012402/maven2-property-that-indicates-the-parent-directory (6认同)
  • $ {session.executionRootDirectory}也是我的神奇子弹.为什么这不在http://maven.apache.org/pom.html? (2认同)

Gré*_*eph 26

从Maven 3.3.1开始,就可以${maven.multiModuleProjectDirectory}用于此目的.(感谢/sf/answers/3421568811/)

编辑:当您.mvn在项目的根目录中有一个文件夹时,这似乎只能正常工作.

  • @kaqqao是的,这很奇怪.我不能说我完全理解那个bug报告的内容,但是当我尝试`mvn help:evaluate -Dexpression = maven.multiModuleProjectDirectory`它对我有用¯\\ _(ツ)_ /¯编辑:我意识到它似乎只有当我的项目顶部有一个`.mvn`文件夹时才能工作! (4认同)
  • 尝试使用maven 3.6.3。结论: 1) 必须有一个 `.mvn` 文件夹,但它可以为空 2) 即使从子目录(模块)运行命令,mvn 也会正确报告整个项目的根目录。 (4认同)
  • @ChristofferHammarström 出于某种原因只出现在 3.3.9 的发行说明中作为错误修复:https://maven.apache.org/docs/3.3.9/release-notes.html 但在 Maven 的 Jira 项目中进一步挖掘,这是它被引入的地方,并且确实被标记为 3.3.1 固定:https://issues.apache.org/jira/browse/MNG-5767 (2认同)
  • 可悲的是,他们“修复”了它,现在它只指向当前的子项目,而不是实际的多项目根。所以它并不比其他选择好。 (2认同)
  • 为我工作 **没有 ** 根目录中的 `.mvn` 文件夹。 (2认同)
  • 请不要在任何时候使用这个属性。这是一个内部属性(实现细节)。它可能会随着释放而消失。 (2认同)
  • @GrégoryJoseph https://issues.apache.org/jira/browse/MNG-7038 (2认同)

小智 22

我在我的项目中使用的东西是覆盖子模块poms中的属性.

    root:           <myproject.root>${basedir}</myproject.root>
    moduleA:        <myproject.root>${basedir}/..</myproject.root>
    other/moduleX:  <myproject.root>${basedir}/../..</myproject.root>

这样你仍然拥有相对路径,但你可以在根模块中定义一个插件,你的模块将继承它,并正确替换myproject.root.

  • 你打算管理所有这些"/ .."和"/../ .."吗?我的意思是,确定这个解决方案有效,但它隐藏了项目的实际结构. (4认同)
  • 谢谢!对于简单的项目,这是最优雅的方式。没有额外的插件,只是显式覆盖。+1 (2认同)

And*_*ejs 18

有一个maven插件可以解决这个特殊问题:directory-maven-plugin

它会将项目的根路径分配给您选择的属性.查看highest-basedir文档中的目标.

例如:

<!-- Directory plugin to find parent root directory absolute path -->
<plugin>
  <groupId>org.commonjava.maven.plugins</groupId>
  <artifactId>directory-maven-plugin</artifactId>
  <version>0.1</version>
  <executions>
    <execution>
      <id>directories</id>
      <goals>
        <goal>highest-basedir</goal>
      </goals>
      <phase>initialize</phase>
      <configuration>
        <property>main.basedir</property>
      </configuration>
    </execution>
  </executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)

然后${main.basedir}在父/子pom.xml中的任何位置使用.

  • 我建议*避免*这个解决方案:如果你没有执行阶段(在例子中是`initialize`),属性将无法解决,所以,如果你需要它,例如在`clean/pre的子模块上-clean`阶段你会发现自己在子模块上复制/破解配置(已在各种项目中看到它).除非您有特殊要求,否则请使用@karel的解决方案(不,您的项目并不特殊). (3认同)

小智 7

正如其他人所建议的那样,directory-maven-plugin是要走的路。但是,我发现它最适合directory-of目标,如下所述:https : //stackoverflow.com/a/37965143/6498617

我更喜欢这样,因为使用highest-basedir嵌套的多模块 poms 的多模块项目对我不起作用。该directory-of目标允许您将属性设置为整个项目中任何模块的路径,当然包括根。它也比 好得多${session.executionRootDirectory},因为它始终有效,无论您是构建根模块还是子模块,也无论您 mvn 来自哪个当前工作目录。


Ser*_*nov 6

目前,Maven 不提供这样的开箱即用的 \xc2\xabRoot 项目目录路径\xc2\xbb 属性。
\n\xc2\xabRoot project\xc2\xbb 表示 \xc2\xabtopmost\xc2\xbb 父项目。

\n

请参阅票证并考虑投票:[MNG-7038] 引入公共属性以指向(多模块)项目 - ASF JIRA 的根目录

\n


Pas*_*ent 1

我不知道找到多模块项目的根的“好”方法。但你也许可以改进一下你当前的方法。

第一个替代方案是直接在根项目下创建一个附加模块,将所有 EAR 声明为其中的依赖项,并用于将dependency:copy-dependencies模块的依赖项复制到目录to-deploy(相对)。是的,路径仍然是相对的,但由于依赖插件配置将是集中的,我觉得它并不那么烦人。

第二种选择是使用Maven 程序集插件而不是Maven 依赖项插件来创建使用dir格式的发行版(这将在目录中创建发行版)。这实际上就是我要做的。