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

我想使用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/ ... 

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

  <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>元素中指定一个相对path。 我喜欢像${reactor.root.directory}/../to-deploy ,但我找不到像这样的东西。

另外,我宁愿如果有某种方式来inheritance这个Maven的依赖插件configuration,所以我不必为每个EAR模块指定它。

我也尝试从根pominheritance自定义属性:

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

但是当我试图在耳模块POM中使用${myproject.root}时, ${basedir}将会parsing为耳模块的basedir。

此外,我发现http://labs.consol.de/lang/de/blog/maven/project-root-path-in-a-maven-multi-module-project/其中build议每个开发人员和推测连续集成服务器应该在profiles.xml文件中configuration根目录,但我不认为它是一个解决scheme。

那么有没有简单的方法来find一个多模块项目的根?

使用${session.executionRootDirectory}

为了logging, ${session.executionRootDirectory}适用于Maven 3.0.3中的pom文件。 该属性将是您正在运行的目录,所以运行父项目,每个模块都可以获取该根目录的path。

我把在父pom中使用这个属性的插件configuration,以便它被inheritance。 我在configuration文件中使用它,当我知道我要在父项目上运行Maven时,我只会select它。 这样,当我在一个子项目上运行Maven(因为这个variables不会是父项的path)时,我不太可能以一种不希望的方式使用这个variables。

例如,

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

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

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

这样你仍然有相对的path,但是你可以在根模块中定义一个插件,你的模块将inheritance它,并为myproject.root取代它。

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

它会将项目的根path分配给您select的属性。 在文档中查看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}

正如其他人所说,directory-maven-plugin是要走的路。 不过,我发现它与'目录'的目标最好的工作,如下所述: https : //stackoverflow.com/a/37965143/6498617 。

我更喜欢使用最高basedir对于多模块项目,嵌套多模块poms不工作。 目标目录允许您将属性设置为整个项目中任何模块的path,包括当然的根目录。 它也比$ {session.executionRootDirectory}更好,因为它总是可以工作的,不pipe你是build立根还是子模块,而不pipe当前你的mvn工作目录。

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

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

我没有意识到find多模块项目的根的“好方法”。 但是你也许可以改进一下你目前的方法。

第一种方法是直接在根项目下创build一个附加模块,将所有EAR声明为依赖关系,并使用dependency:copy-dependencies关系将模块的依赖dependency:copy-dependencies复制到待to-deploy目录(相对)。 是的path仍然是相对的,但由于依赖插件configuration将集中,我不觉得这很烦人。

第二种方法是使用Maven Assembly Plugin代替Maven Dependency Plugin来使用dir格式创build一个分发(这将在目录中创build一个分发)。 这实际上是我会做的。

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

以下小档案为我工作。 我需要这样一个configurationCheckStyle,我把它放到项目根目录下的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几个configuration文件。 (我不知道为什么在validation标签中应该有“../ ..”,而在overriden属性本身中只是“..”,但它只能以这种方式工作。)

所以:在某些父项属性的某个地方项目我有我需要稍后关系的文件,这就是为什么我需要绝对path到处。 所以,我在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> 

有用!