Java Maven 和依赖模块
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/808516/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Maven and dependent modules
提问by David
Colleagues have been touting the wonders of maven and its magical dependency stuff but I'm finding that it fails at what I would consider the obvious use.
同事们一直在吹捧 maven 的奇迹及其神奇的依赖关系,但我发现它在我认为明显的用途方面失败了。
Suppose I have a root folder with a master POM.
假设我有一个带有主 POM 的根文件夹。
Then underneath I have some projects, call them A and B
然后在下面我有一些项目,称它们为 A 和 B
B requires A and so the POM in the B folder has the appropriate dependency entry in it
B 需要 A,因此 B 文件夹中的 POM 中有相应的依赖项
Now, back in the root folder, in a profile, I specify that I want to build B.
现在,回到根文件夹,在一个配置文件中,我指定我要构建 B。
When I perform the usual mvn clean install, I get a failure because A was not built.
当我执行通常的 mvn 全新安装时,我失败了,因为 A 没有构建。
My friends tell me I have to specify both A and B in that main profile in the root.
我的朋友告诉我,我必须在根目录的主配置文件中指定 A 和 B。
But isn't the whole point of dependency management that maven sees B, goes to the B POM file where it sees the dependency on A and so it should go build A automatically.
但是,maven 看到 B 并不是依赖管理的全部重点,而是转到 B POM 文件,在那里它看到对 A 的依赖,因此它应该自动构建 A。
采纳答案by Rich Seller
A reason I can think of that your desired behaviour hasn't been implemented is as follows:
我能想到的您想要的行为尚未实现的原因如下:
Suppose I'm working on both projects A and B. Currently A is broken. If dependency resolution happened as you would like, I would never be able to build B until A was fixed. So I either have to roll back my changes to A, or focus on fixing A first. Either way possibly not what I want to focus on right now.
假设我正在处理项目 A 和 B。目前 A 已损坏。如果依赖解析如你所愿,在 A 被修复之前,我将永远无法构建 B。所以我要么必须回滚我对 A 的更改,要么首先专注于修复 A。无论哪种方式,可能都不是我现在想要关注的。
Generally B wants to work with the "last good" version of A, rather than the latest. Using the dependencies from the repository means they at least compiled ok (and hopefully the unit tests were run too).
通常 B 想要使用 A 的“最后一个好”版本,而不是最新版本。使用存储库中的依赖项意味着它们至少可以正常编译(并且希望单元测试也能运行)。
回答by millimoose
With the master POM:
使用主 POM:
~/scratch/pom.xml
~/scratch/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>scratch</groupId>
<artifactId>scratch</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>nipple</module>
<module>cabbage</module>
</modules>
</project>
And the module POMs:
和模块 POM:
~/scratch/nipple/pom.xml
~/scratch/nipple/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>scratch</artifactId>
<groupId>scratch</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>scratch</groupId>
<artifactId>nipple</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
~/scratch/cabbage/pom.xml
~/scratch/cabbage/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>scratch</artifactId>
<groupId>scratch</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>scratch</groupId>
<artifactId>cabbage</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>scratch</groupId>
<artifactId>nipple</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
I can issue mvn package
in the root directory after clearing out my local repository and end up with all the modules built. (Into empty-ish JARs, but built.)
mvn package
在清除我的本地存储库并最终构建所有模块后,我可以在根目录中发出问题。(进入空的 JAR,但已构建。)
Maven seems to look for dependencies either in the repository, or in the build in progress. It will not automatically traverse your project structure when you're only building a single module, because it's not required that you even have the parent project on your computer, much less one directory above the current module. (The parent-child relationship isn't even bijective.)
Maven 似乎在存储库或正在进行的构建中查找依赖项。当您只构建单个模块时,它不会自动遍历您的项目结构,因为它甚至不需要您的计算机上有父项目,更不用说当前模块上方的一个目录了。(亲子关系甚至不是双射的。)
A reason why this is so might be because a directory layout where the location of modules would be predictable is in no way mandatory. It's even somewhat common and acceptable that the layout for the above example be like this:
之所以如此,可能是因为模块位置可预测的目录布局绝不是强制性的。上面例子的布局是这样的,甚至有点普遍和可接受:
projects
|
+--scratch
| |
| +--scratch-parent
| | |
| | +--pom.xml [The POM of scratch:scratch:1.0-SNAPSHOT]
| |
| +--nipple
| | |
| | +--pom.xml [The POM of scratch:mod1:1.0-SNAPSHOT]
| |
| +--cabbage
| | |
| | +--pom.xml [The POM of scratch:mod2:1.0-SNAPSHOT]
In this case, the <modules>
section of the parent POM would be:
在这种情况下,<modules>
父 POM的部分将是:
<modules>
<module>../nipple</module>
<module>../cabbage</module>
</modules>
Notice that there is nothing saying whichartifact ID is in which module. It just serves to tell Maven that these are filesystem locations where to search for other artifacts related to this build.
请注意,没有说明哪个工件 ID 位于哪个模块中。它只是告诉 Maven,这些是文件系统位置,可以在其中搜索与此构建相关的其他工件。
回答by deterb
Take a look at the Maven reactor plugin, in particular reactor:make, which builds a module and all of the modules which it depends on.
看看Maven reactor 插件,特别是 reactor:make,它构建了一个模块和它所依赖的所有模块。
回答by mmuller
Rich is totally right. What you describe is generally not the expected behaviour. Although, as stated by deterb, the Maven reactor supports partial builds if the modules are known by the parent POM.
富是完全正确的。您所描述的通常不是预期的行为。尽管如 deterb 所述,如果父 POM 知道模块,Maven 反应器支持部分构建。
Building with mvn install -pl B -am
should also make(-am
) B's dependencies (that is, A).
构建也mvn install -pl B -am
应该使( -am
) B 的依赖项(即 A)。
Anyway, module A mustbe a module of the parent POM.
无论如何,模块 A必须是父 POM 的模块。
(see Maven Modules + Building a Single Specific Module)
(请参阅Maven 模块 + 构建单个特定模块)
回答by T Rob Darrough
The answer is just that its not the way Maven works. The idea behind Maven is to give the developer a logical, simple system for controlling dependencies. Getting dependencies from the repository is the key to this. Every exception weakens this control and simplicity. Adding A as a dependency in the parent POM fully addresses your scenario without adding further exceptions. Using batch files or ant scripts is another way to address your scenario.
答案只是它不是 Maven 的工作方式。Maven 背后的想法是为开发人员提供一个逻辑的、简单的系统来控制依赖关系。从存储库中获取依赖项是实现这一目标的关键。每一个例外都会削弱这种控制和简单性。在父 POM 中添加 A 作为依赖项可以完全解决您的场景,而无需添加更多异常。使用批处理文件或 ant 脚本是另一种解决方案的方法。
回答by Tomer
If you're working with IntelliJ, they have a little magic checkbox: "Resolve Workspace Artifacts" in their Maven run configuration. So no need to install nor build from the parent.
如果你使用 IntelliJ,他们有一个小魔法复选框:在他们的 Maven 运行配置中“解析工作区工件”。因此无需从父级安装或构建。