我想使用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文件中配置根目录,但我不认为它是一个解决方案。
那么有一种简单的方法可以找到多模块项目的根目录吗?
答案 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的根目录。