查找多模块 Maven Reactor 项目的根目录
有没有一种简单的方法可以找到多模块 Maven 项目的根目录,例如 Gradle 的 rootDir
?
背景:
我想使用 maven-dependency-plugin 将多模块项目的所有子模块中的工件复制到相对于整个项目的根目录的目录。
也就是说,我的布局看起来与此类似,名称已更改:
to-deploy/
my-project/
module-a/
module-b/
more-modules-1/
module-c/
module-d/
more-modules-2/
module-e/
module-f/
...
并且我希望将所有工件从各自模块的目标目录复制到 my-project/../to-deploy
所以我最终
to-deploy/
module-a.jar
module-b.jar
module-c.jar
module-d.jar
module-e.jar
module-f.jar
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>jar</type>
<outputDirectory>../../to-deploy</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
但我不想在
元素中指定相对路径。
我更喜欢像 ${reactor.root.directory}/../to-deploy
这样的东西,但我找不到这样的东西。
另外,我希望有某种方法可以继承此 maven-dependency-plugin 配置,这样我就不必为每个模块指定它。
我还尝试从根 pom 继承自定义属性:
<properties>
<myproject.root>${basedir}</myproject.root>
</properties>
但是当我尝试在模块 POM 中使用 ${myproject.root}
时,${basedir}
将解析到模块的 basedir。
另外,我发现 http://labs.consol.de/lang/de/blog/maven/project-root-path-in-a-maven-multi-module-project/ 建议每个开发人员并且大概持续集成服务器应该在profiles.xml文件中配置根目录,但我不认为这是一个解决方案。
那么有没有一种简单的方法来找到多模块项目的根呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
使用
${session.executionRootDirectory}
作为记录,
${session.executionRootDirectory}
在 Maven 3.0.3 的 pom 文件中为我工作。该属性将是您正在运行的目录,因此运行父项目,每个模块都可以获取该根目录的路径。我将使用此属性的插件配置放在父 pom 中,以便它被继承。我在配置文件中使用它,仅当我知道要在父项目上运行 Maven 时才选择该配置文件。这样,当我在子项目上运行 Maven 时,我就不太可能以不希望的方式使用此变量(因为这样该变量将不是父项目的路径)。
例如,
use
${session.executionRootDirectory}
For the record,
${session.executionRootDirectory}
works for me in pom files in Maven 3.0.3. That property will be the directory you're running in, so run the parent project and each module can get the path to that root directory.I put the plugin configuration that uses this property in the parent pom so that it's inherited. I use it in a profile that I only select when I know that I'm going to run Maven on the parent project. This way, it's less likely that I'll use this variable in an undesired way when I run Maven on a child project (because then the variable would not be the path to the parent).
For example,
从 Maven 3.3.1 开始,您可以使用
${maven.multiModuleProjectDirectory}
来实现此目的。(感谢 https://stackoverflow.com/a/48879554/302789)
编辑:这似乎只有在以下情况下才能正常工作您的项目根目录下有一个
.mvn
文件夹。Since Maven 3.3.1, you can use
${maven.multiModuleProjectDirectory}
for this purpose.(thanks to https://stackoverflow.com/a/48879554/302789)
edit: this seems to only work properly when you have a
.mvn
folder at the root of your project.我在项目中使用的方法是覆盖子模块 poms 中的属性。
这样,您仍然拥有相对路径,但您可以在根模块中定义一次插件,并且您的模块将通过正确替换 myproject.root 来继承它。
Something which I have used in my projects is to override the property in the sub-module poms.
This way you still have the relative paths, but you can define a plugin once in the root module, and your modules will inherit it with the right substitution for myproject.root.
有一个maven插件可以解决这个特殊问题: directory-maven-plugin
它将分配您的项目到您选择的属性的根路径。请参阅文档中的
highest-basedir
目标。例如:
然后在父/子 pom.xml 中的任何位置使用
${main.basedir}
。There is a maven plugin that solves this particular problem: directory-maven-plugin
It will assign the root path of your project to a property of your choosing. See
highest-basedir
goal in the docs.For example:
Then use
${main.basedir}
anywhere in your parent / child pom.xml.正如其他人所建议的,
directory-maven-plugin
是正确的选择。但是,我发现它最适合
directory-of
目标,如下所述:https://stackoverflow .com/a/37965143/6498617。我更喜欢这样,因为使用
highest-basedir
不适用于具有嵌套多模块 pom 的多模块项目。directory-of
目标允许您将属性设置为整个项目中任何模块的路径,当然包括根目录。它也比 ${session.executionRootDirectory} 好得多,因为无论您构建的是根模块还是子模块,也无论您从哪个 mvn 当前工作目录,它总是有效。
As others have suggested,
directory-maven-plugin
is the way to go.However, I found it works best with the
directory-of
goal, as described here: https://stackoverflow.com/a/37965143/6498617.I prefer that as using
highest-basedir
didn't work for me with a multi-module project, with nested multi-module poms. Thedirectory-of
goal lets you set a property to the path of any module in the whole project, including the root of course.It is also way better than
${session.executionRootDirectory}
, because it always works, regardless of whether you build the root or a sub-module, and irrespective of the current working directory where you mvn from.目前,Maven 不提供这样的“根项目目录路径”属性。
“根项目”是指“最顶层”父项目。
请参阅票证并考虑投票:[MNG-7038] Introduce public property to指向(多模块)项目的根目录 - ASF JIRA。
Currently, Maven does not provide such the «Root project directory path» property out of the box.
«Root project» means the «topmost» parent project.
Please, refer to the ticket and consider voting for it: [MNG-7038] Introduce public property to point to a root directory of (multi-module) project - ASF JIRA.
以下小简介对我有用。我需要这样的 CheckStyle 配置,我将其放入项目根目录的 config 目录中,这样我就可以从主模块和子模块运行它。
它不适用于嵌套模块,但我确信可以使用具有不同
exists
的多个配置文件对其进行修改。 (我不知道为什么验证标签中应该有“../..”,而重写属性本身只有“..”,但它只能以这种方式工作。)The following small profile worked for me. I needed such a configuration for CheckStyle, which I put into the
config
directory in the root of the project, so I can run it from the main module and from submodules.It won't work for nested modules, but I'm sure it can be modified for that using several profiles with different
exists
's. (I have no idea why there should be "../.." in the verification tag and just ".." in the overriden property itself, but it works only in that way.)我遇到了类似的问题,因为我需要在项目之间复制文件。 Maven 所做的事情是合乎逻辑的,因为它将使安装在存储库中的 pom.xml 远离硬编码值。
我的解决方案是将复制的目录放入 Maven 工件中,然后使用 Ant 提取/复制
I encountered similar problem as i needed to copy files between projects. What Maven does is logical because it will keep the pom.xml installed in repository away from hard coded value.
My solution was to put copied dir in a Maven artifact, then employ Ant to extract/copy
除了使用绝对根路径之外,在某些情况下,我还有另一种方法来解决问题。
使用maven插件combine.children功能,参考:maven插件
我可以编写我的代码:
parent pom:
或者写在插件管理中,如果parent pom不使用该插件。
子pom:
类似的方式
孙子 pom:
Except use absolutely root path, in some case, I have another way to solve the problem.
Use maven plugin combine.children feature, refs: maven plugin
I can write my code:
parent pom:
or write in plugin management, if parent pom doesn't use this plugin.
child pom:
Similar way
grandchild pom:
我不知道找到多模块项目的根的“好”方法。但你也许可以改进一下你当前的方法。
第一种选择是直接在根项目下创建一个附加模块,将所有 EAR 声明为其中的依赖项并使用
dependency:copy-dependencies
将模块的依赖项复制到to-deploy
目录(相对)。是的,路径仍然是相对的,但由于依赖插件配置将是集中的,我觉得它并不那么烦人。第二种选择是使用 Maven Assembly Plugin 而不是 < a href="http://maven.apache.org/plugins/maven-dependency-plugin/" rel="nofollow noreferrer">Maven 依赖插件 使用 dir 格式(这将在目录中创建一个发行版)。这实际上就是我要做的。
I'm not aware of a "nice" way to find the root of a multi-module project. But you can maybe improve a bit your current approach.
A first alternative would be to create an additional module directly under the root project, to declare all EARs as dependencies in it and to use
dependency:copy-dependencies
to copy the dependencies of the module to theto-deploy
directory (relatively). Yes the path would still be relative but since the dependency plugin configuration would be centralized, I don't find it that annoying.A second alternative would be to use the Maven Assembly Plugin instead of the Maven Dependency Plugin to create a distribution using the dir format (this will create a distribution in a directory). This is actually what I would do.
另一个解决方案是使用 ant 任务将“rootdir=${basedir}”写入根项目中的 target/root.properties,然后使用 属性插件 来读回该文件。我自己还没有尝试过,但我想它应该可以工作..?
Another solution would be to use an ant task to write "rootdir=${basedir}" to a target/root.properties in the root project, and then use the Properties Plugin to read that file back in. I haven't tried it myself, but I guess it should work..?
你可以选择这样的东西。请注意,您必须定义两个配置文件 - 一个将为根目录激活,另一个为子目录激活。显然,这假设孩子们将具有相同的结构,但这可以很容易地适应。
You can go with something like this. Note, that you have to define two profiles - one which will be activated for the root directory and one for children. Obviously this assumes children will have the same structure but this can be easily adapted.
这样:在某个父项目的属性中的某个位置,我有稍后需要关联的文件,这就是为什么我在任何地方都需要它的绝对路径。所以,我在groovy的帮助下得到了它:
然后:
它起作用了!
so that: somewhere in properties of some parent Project I've the file which i need to relate later, what's why i need absolute path on it everywhere. So, i get it with help of groovy:
and then:
it works!
使用 Maven 4(自 4.0.0-beta7 起实施,请参阅 MNG-7038 )您可以使用
project.rootDirectory
变量,其中根目录是通过使用.mvn
目录或使用新的 pom 属性root=true< 来定义的/code> 是在新的 pom 模型版本 4.1.0 中与 Maven 4 一起引入的。
然后使用该变量,例如
With Maven 4 (implemented since 4.0.0-beta7, see MNG-7038) you can use the
project.rootDirectory
variable, where the root directory is definied either by using a.mvn
directory or using the new pom attributeroot=true
which is introduced with the new pom model version 4.1.0 together with Maven 4.and then use the variable, e.g.
<excludeFromFailureFile>${project.rootDirectory}/exclude-pmd.properties</excludeFromFailureFile>
对于 Maven 3.6.1,从子项目中,${parent.basedir} 返回父项目的完全限定目录。
With Maven 3.6.1, from a child project, ${parent.basedir} returns the fully qualified directory of the parent project.
我有 ${project.parent.basedir} 的父 pom 的根目录。
I've got root directory for parent pom with ${project.parent.basedir}.