我有一个多模块项目,即
parent
module1
module2
在一个开发周期中,我向module1添加了一个类mod1.A
。module2中的类mod2.B
依赖于它。
我的本地.m2/repository
中没有工件。运行以下命令:
$ cd prj/module2
$ mvn -o exec:java -Dexec.mainClass=mod2.B
会导致以下错误:
The following artifacts could not be resolved: com.example:module1:jar:1.0-SNAPSHOT
当我在prj
文件夹中通过mvn install
安装工件后,一切都按预期工作。
然而,这在至少两个方面提出了问题:
- 我必须经历较慢的安装阶段,而不是较快的编译阶段
- 我有同一个项目的两个版本,并且在这两个版本中有相互冲突的修改。我不能用它们各自的修改运行同一个Java类,只能运行当前安装的修改,因为它们都是相同的SNAPSHOT版本
这两种方法都有解决方法(第一种方法跳过构建的一部分,第二种方法跳过不同的快照版本),但它们在实践中远不能使用。
有没有办法让maven使用本地模块,而不是使用本地maven资源库中的工件?
3条答案
按热度按时间06odsfpq1#
如果我没理解错你的问题的话,你的生活似乎有点不正常:你有两个本地的项目“副本”,有不同的修改,你想在运行“exec:java”的时候交替使用它们。2 Maven妨碍了你:它希望本地
.m2
存储库区域处于活动状态,但是每个副本中的版本字符串都是相同的,因此最终会出现副本之间的更改冲突。对我来说,这听起来像是您要测试您的更改。我建议您只在module 2中编写一个实际的JUnit或TestNG测试来测试您想要的内容(如果您愿意,它可以只调用mod2.B Main)。然后,从您选择的项目目录中,您可以运行
mvn test -Dtest=MyTestName
。它不会“安装”任何东西,它会按照您想要的方式找到依赖项。否则,我可以看到三个选择。
1.在其中一个副本中本地更改版本字符串(
mvn versions:set -DnewVersion=B-SNAPSHOT
可以为您做这件事)。这样,您在该副本上的工作中“安装”的任何jar文件都不会被其他副本考虑,反之亦然。你说这是“远远不能使用”...我想应该没问题吧?这是项目的不同版本!它们应该有不同的版本字符串!我强烈推荐这三个选项中的这个选项。(如果使用:set
,则可以在完成后执行mvn versions:revert
,或者可以依靠版本控制来撤消更改。)1.选择一个不同的本地存储库,Maven在处理其中一个项目时使用,命令行标记为https://stackoverflow.com/a/7071791/58549。我真的不认为这是一个好的解决方案,因为您必须非常小心地在每次处理两个项目时使用正确的标记。而且,您最终必须重新下载Maven插件和任何其他依赖项到新的本地存储库中。这有点浪费时间。
1.尽量避免使用 * 任何 * 本地存储库 *。你似乎在尝试让这个选项起作用。我也不认为这是一个好的方法;您正在与Maven的期望作斗争,这极大地限制了您的灵活性。Maven确实会首先从“reactor”(即,正在执行的
mvn
进程)中找到依赖项,但这意味着所有需要的模块必须在要找到的reactor中可用,这意味着您只能在顶层运行mvn
。因此,如果您只想在单个模块中执行“mvn exec:java”,mvn需要在某处找到该模块的依赖项...这就是通常使用本地repo的目的。如果你执意选择选项3(而不是选项1),那么我建议你按照问题上的评论,创建一个配置文件,有选择地对module 2运行
exec
,并将其绑定到一个生命周期阶段。chhkpiq42#
对于IntelliJ用户:
我用IntelliJ的Run配置解决了这个问题。它有
Resolve workspace artifacts
和Add before launch task
-〉Build
选项。请看下面的图片来澄清:Run configuration example
bjg7j2ky3#
Maven中模块的全部意义在于创建它们之间的解耦。您可以独立构建每个模块,这样您可以在不接触另一个模块的情况下处理一个模块,或者将两个模块作为子模块包含在父pom中并构建父pom,这将解决其子模块之间的依赖关系并触发它们的构建。
看起来您有两个选择:
1.检查项目的结构。如果同时更改两个模块中的代码,是否真的需要将项目拆分为两个单独的模块?
1.将项目导入到一个支持Maven的IDE中(IntelliJ IDEA非常擅长使用Maven),让IDE处理编译。完成并稳定代码库后,使用Maven进行正常构建。