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

时间:2010-06-21 12:34:47

标签: maven-2 directory 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/
    ...

我希望将所有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/
    ...

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

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

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

另外,我更喜欢是否有某种方法可以继承这个maven-dependency-plugin配置,所以我不必为每个EAR模块指定它。

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

<properties>
    <myproject.root>${basedir}</myproject.root>
</properties>

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

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

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

13 个答案:

答案 0 :(得分:65)

使用${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>

答案 1 :(得分:20)

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

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

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

答案 2 :(得分:20)

从Maven 3.3.1开始,您可以使用${maven.multiModuleProjectDirectory}来实现此目的。 (感谢https://stackoverflow.com/a/48879554/302789

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

答案 3 :(得分:16)

有一个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>

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

答案 4 :(得分:4)

正如其他人所建议的那样,directory-maven-plugin是最佳选择。 但是,我发现它最适合“目录”目标,如下所述:https://stackoverflow.com/a/37965143/6498617

我更喜欢使用带有嵌入式多模块poms的多模块项目,使用基于最高版本的对我不起作用。目标目录允许您将属性设置为整个项目中任何模块的路径,包括当然的根。 它也比$ {session.executionRootDirectory}更好,因为它总是有效,无论你是构建根模块还是子模块,而不管你当前的工作目录是什么。

答案 5 :(得分:2)

我遇到了类似的问题,因为我需要在项目之间复制文件。 Maven所做的是合乎逻辑的,因为它会使存储库中安装的pom.xml远离硬编码值。

我的解决方案是将复制的dir放在Maven工件中,然后使用Ant来提取/复制

答案 6 :(得分:1)

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

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

第二种方法是使用Maven Assembly Plugin而不是Maven Dependency Plugin来使用 dir 格式创建分发(这将在目录中创建分发)。这实际上就是我要做的。

答案 7 :(得分:1)

另一个解决方案是使用ant任务将“rootdir = $ {basedir}”写入根项目中的target / root.properties,然后使用Properties Plugin重新读取该文件。我自己没有尝试过,但我想它应该可行..?

答案 8 :(得分:1)

以下小资料为我工作。我需要CheckStyle这样的配置,我把它放在项目根目录的config目录中,所以我可以从主模块和子模块运行它。

<profile>
    <id>root-dir</id>
    <activation>
        <file>
            <exists>${project.basedir}/../../config/checkstyle.xml</exists>
        </file>
    </activation>
    <properties>
        <project.config.path>${project.basedir}/../config</project.config.path>
    </properties>
</profile>

它不适用于嵌套模块,但我确信可以使用具有不同exists的多个配置文件对其进行修改。 (我不知道为什么在验证标签中应该有“../ ..”而在overriden属性本身中只有“..”,但它只能以这种方式工作。)

答案 9 :(得分:0)

所以:某些父项目属性中的某个地方我以后需要关联的文件,这就是为什么我需要它到处都是绝对路径的原因。所以,我在 groovy

的帮助下得到它
<properties>    
<source> import java.io.File; 
        String p =project.properties['env-properties-file']; 
        File f = new File(p); 
        if (!f.exists()) 
        { 
           f = new File("../" + p); 
          if (!f.exists()) 
          { 
             f = new File("../../" + p); 
          } 
        } 
        // setting path together with file name in variable xyz_format 
        project.properties['xyz_format'] =f.getAbsolutePath() 
                            + File.separator 
                            + "abc_format.xml"; 
</source>
</properties>   

然后:

  <properties>
     <snapshots>http://localhost:8081/snapshots<snapshots>
     <releases>http://localhost:8081/releases</releases>
     <sonar>jdbc:oracle:thin:sonar/sonar@localhost/XE</sonar>
     <sonar.jdbc.username>sonar</sonar.jdbc.username>
     <format.conf> ${xyz_format}</format.conf>  <---- here is it!
    </properties>

它有效!

答案 10 :(得分:0)

您可以使用类似这样的东西。请注意,您必须定义两个配置文件-一个将针对根目录被激活,另一个针对子目录被激活。显然,这是假定孩子具有相同的结构,但是可以很容易地对其进行调整。

    <profiles>
        <profile>
            <id>root-dir</id>
            <activation>
                <file>
                    <exists>${basedir}/lib</exists>
                </file>
            </activation>
            <properties>
                <project.libdir>${basedir}/lib</project.libdir>
            </properties>
        </profile>
        <profile>
            <id>child-dir</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <project.libdir>${basedir}/../../lib</project.libdir>
            </properties>
        </profile>
    </profiles>

答案 11 :(得分:0)

在Maven 3.6.1中,$ {parent.basedir}从子项目中返回父项目的完全限定目录。

答案 12 :(得分:0)

我已经有了$ {project.parent.basedir}的父pom的根目录。