Maven和依赖模块
同事一直在兜售Maven的奇迹和它的神奇依赖的东西,但是我发现它在我认为明显的用途上失败了。
假设我有一个主POM的根文件夹。
然后在下面我有一些项目,叫他们A和B
B需要A,因此B文件夹中的POM在其中具有适当的相关性条目
现在,回到根文件夹中,在一个configuration文件中,我指定我要构buildB.
当我执行通常的mvn干净安装时,我得到一个失败,因为没有build立。
我的朋友告诉我,我必须在根中的主configuration文件中指定A和B.
但是,不是maven看到B的依赖pipe理的全部观点,而是去看看对A的依赖关系的B POM文件,所以它应该自动地去构buildA.
我能想到的一个理由是,你所期望的行为还没有被执行如下:
假设我正在项目A和B上工作。目前A已经坏了。 如果依赖的解决方法发生了,我将永远无法build立B,直到A被修复。 所以我要么必须将我的更改回滚到A,要么首先关注修复A. 无论哪种方式可能不是我现在想要关注的。
一般来说,B想和A的“最后一个好”版本一起工作,而不是最新版本。 使用存储库中的依赖关系意味着至less编译好了(希望unit testing也可以运行)。
与主POM:
~/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>
和模块POMs:
~/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
<?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>
清除我的本地存储库后,我可以在根目录下发出mvn package
,并结束所有build立的模块。 (进入空的JAR,但build成。)
Maven似乎在存储库或正在进行的构build中寻找依赖关系。 当您只构build单个模块时,它不会自动遍历您的项目结构,因为您甚至不需要在您的计算机上拥有父项目,更不用说在当前模块之上的一个目录。 (亲子关系甚至不是双射的。)
原因之所以如此,可能是因为模块的位置是可预测的目录布局决不是强制性的。 上面例子的布局是这样的:
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]
在这种情况下,父POM的<modules>
部分将是:
<modules> <module>../nipple</module> <module>../cabbage</module> </modules>
请注意,没有什么可以说明哪个工件ID在哪个模块中。 它只是告诉Maven这些文件系统位置在哪里search与此构build相关的其他工件。
看看Maven反应器插件 ,特别是反应器:make,它build立一个模块和所有依赖的模块。
Rich是完全正确的。 你所描述的一般不是预期的行为。 虽然,正如威廉所说, 如果模块被父POM知道 ,Maven反应器支持部分构build。
用mvn install -pl B -am
也应该使 ( -am
)B的依赖(也就是A)。
无论如何,模块A 必须是父POM的模块。
(请参阅Maven模块+构build单个特定模块 )
如果您正在使用IntelliJ,他们的Maven运行configuration中有一个小小的魔术checkbox:“parsing工作区工件”。 所以不需要安装也不需要从父母那里build立。
答案就是它不是Maven的工作方式。 Maven背后的想法是为开发人员提供一个逻辑的,简单的系统来控制依赖关系。 从存储库获取依赖关系是关键。 每个例外都会削弱这种控制和简单性。 在父POM中添加A作为依赖关系完全解决了您的scheme,而无需添加其他例外情况。 使用batch file或ant脚本是解决您的情况的另一种方法。