与Maven一起工作了一段时间之后,我对Maven带到构建体系结构中的许多功能特别是依赖管理感到非常兴奋。但是,我一次又一次遇到一个问题-Maven如何解决多模块项目之间的依赖关系。我想知道这是否是当前Maven实现的主要缺陷,并且/或者是否有令人满意的解决方法。
假设我有一个多模块Maven项目。父pom包含三个模块-moduleA(jar),moduleB(jar)和moduleC(war)。 B取决于A,C取决于B。足够简单吗?现在,我想在父项目中运行mvn dependency:go-offline
,该项目应该可以解决所有依赖关系,并将它们带入本地.m2目录。它失败是因为Maven抱怨说,当它作用于模块B时,无法解决模块A的依赖关系。因为所有这些模块都属于一个groupId,所以我什至尝试使用-DexcludeGroupIds=x.y.z
排除这些模块依赖性,但是在同一点它仍然失败。
我理解为什么Maven会抱怨-模块A尚未构建,因此当执行脱机目标时,我的本地或内部存储库中没有模块A:jar工件。但是恕我直言,插件应以不同的方式对待这些模块间依赖性。在这种情况下,它应该简单地忽略它。可能有人争辩说,我可以简单地执行mvn clean install
,该操作会将moduleA:jar安装到本地存储库中。在那之后,运行mvn dependency:go-offline
肯定可以工作。但是,这种解决方法无法达到脱机目标的目的。这个插件使我们能够解决依赖关系并将其拉入本地存储库,而无需构建整个项目。在另一种情况下,我使用了dependency:copy-dependencies
目标,但它存在相同的问题。
[在其他情况下,我也遇到了类似的问题:"mvn clean generate-source" could not resolve dependencies。当我运行mvn clean compile
时,一切正常,但是当我运行mvn clean generate-source
时,它失败了,因为Maven无法解决模块间的依赖性。在这种情况下,是由antrun插件中的@requiresDependencyResolution
引起的。
由于antrun插件和依赖插件都在Maven世界中非常流行,所以我确定我不是唯一遇到此问题的人。是否有人找到解决方案/解决方法?
我怀疑Maven是否会实现这种功能。尽管您的项目有一个共同的父母,并且彼此依赖,但Maven可能不知道在哪里可以找到这些项目以进行构建。它还无法确定是否仅需要构建项目,或者您是否为依赖项指定了错误的版本号。
Maven具有“反应器”的概念,其中在一次运行中构建的工件(例如maven package
)可用于在构建过程中进行依赖项解析。例如,如果依赖图产生了构建顺序moduleA moduleB moduleC,而您执行了mvn package
,则Maven将构建moduleA,打包其工件并将其添加到反应堆中,然后构建moduleB,打包并将其添加到反应堆中,然后对于moduleC相同。这意味着模块B可以访问模块A的工件以解决依赖关系,而模块C可以访问模块A和模块B。仅当实际构建工件时,即运行包目标时,此方法才有效。
问题是,当您因为对工件不感兴趣(如dependency:go-offline
示例)而没有运行软件包目标时,就不会构建已处理模块的工件,因此不会添加到反应堆我也觉得很烦;我认为Maven应该在其模块列表中查看POM文件,并在其中进行查看。但事实并非如此。
总之,解决您的问题的方法是执行mvn package dependency:go-offline
。这不会在您的本地存储库中安装工件(我认为这是非常糟糕的做法),但是会在构建期间将它们[[will放置在反应堆中,这意味着Maven能够将模块B的依赖项解析为已经建立的moduleA。缺点是每个模块都会经过测试和打包,当您要做的全部事情都是dependency:go-offline
时,这是很多工作。无论哪种方式,希望对您有所帮助。