Maven 3 不会从本地存储库更新快照依赖项
Posted
技术标签:
【中文标题】Maven 3 不会从本地存储库更新快照依赖项【英文标题】:Maven 3 does not update snapshot dependency from local repository 【发布时间】:2014-03-27 18:20:01 【问题描述】:我正在尝试在我的 Maven 项目中使用外部库。由于我希望项目在任何机器上开箱即用,我不想使用mvn install
解决方案。因此,我在 pom.xml 中定义了本地存储库:
<dependency>
<groupId>com.test</groupId>
<artifactId>fooLib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
....
<repository>
<id>in-project</id>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
<name>In Project Repo</name>
<url>file://$project.basedir/libRepo</url>
</repository>
问题是当我替换 libRepo
中的 jar 时(不更新版本号,因为它只是另一个快照),即使是 @987654327,也没有使用这个更新的 jar(使用来自 .m2
目录的旧版本) @
如何让maven更新这个jar?
编辑: 根据What exactly is a Maven Snapshot and why do we need it? maven 应尝试查找从不版本的 SNAPSHOT 依赖项,“即使在本地存储库中找到此库的版本”。我的设置有什么问题?
肮脏的解决方案: 根据Maven 2 assembly with dependencies: jar under scope "system" not included 的回答,我的原始解决方案的以下扩展似乎有效:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>hack-binary</id>
<phase>validate</phase>
<configuration>
<file>$repo.path.to.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>com.test</groupId>
<artifactId>fooLib</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
正如对该解决方案的评论所述,它不能单独工作,因此它与in-project
存储库结合使用(当本地.m2
存储库中的依赖项不可用时有效)并且第二部分刷新@987654331 @ 在每次构建期间。
但是我仍然不清楚为什么普通的“SNAPSHOT”机制不起作用(即当前的脏解决方案在没有 SNAPSHOT 的情况下也可以工作,因为本地 .m2
回购每次都会显式更新)。有没有更干净的方法?
解决方案(基于 Aaron 的回答和讨论):问题是我尝试使用 install-file
将文件安装到 libRepo
。实际的解决方案是,如果库更新,使用
mvn deploy:deploy-file -Dfile=fooLib.jar -DgroupId=com.test \
-DartifactId=fooLib -Dversion=1.0-SNAPSHOT -Dpackaging=jar \
-Durl=file://..\libRepo -DrepositoryId=in-project
将其部署到 repo。正确部署后,maven 可以正确处理 SNAPSHOT。
【问题讨论】:
您是在构建依赖项还是在构建主项目时使用mvn -U clean install
?
我仅将 maven 用于“主”项目。 fooLib
不是 maven 项目,是独立构建的。我只想在我的 Maven(“主”)项目中使用 fooLib 的更新快照。
所以你必须手动安装fooLib
,因为它永远不会在你的.m2文件夹中更新,除非它的版本发生变化。
【参考方案1】:
如果您为此使用存储库,那么 Maven 会将 JAR 复制一次到其本地存储库中(通常在 $HOME/.m2/repository/
中)。除非版本号更改,否则 Maven 不会认为此文件已更改并且不会复制它。请注意,版本号是 Maven 唯一查看的内容;它不关心校验和、文件大小或日期。
顺便说一下,快照在内部被分配一个版本号只是为了这个目的:这样 Maven 可以在内部注意到快照已被更新。
我建议改用system dependency。这样,实际的 JAR 将被添加到类路径中(无需任何复制或其他内容)。你也不需要为这种方法复制一个 repo 结构,它会清楚地传达你的意图。
[编辑] 我了解 Maven 以不同方式处理范围 system
的依赖项。我不确定这是否有意义(如果它使用依赖来编译,它肯定可以使用它来运行?)
在我看来,您有以下选择:
使用deploy:deploy-file 将依赖项安装到您的libRepo
中,而不是自己复制它。这应该以这样一种方式更新元数据,当您在真实项目上再次运行 mvn install
时,Maven 会再次复制它。
请注意,file:install
不起作用。文件插件用于访问本地存储库,但您需要使用知道如何更新共享/服务器存储库的部署插件。
将依赖项安装到您的本地仓库中;我建议为此使用可以包含在项目中的脚本。这样一来,您就可以避免所有问题,并且很容易在新机器上进行设置。
更改依赖的版本号,但这很繁琐,当依赖的真实版本号更改时,您可能会遇到麻烦。
为您的公司设置本地 repo 服务器并将依赖项部署到它。这将需要几个小时,但是 a) 您将获得所有依赖项的本地缓存,从而使您的初始构建更快;b) 它将使其他开发人员的设置速度更快。
【讨论】:
起初它看起来很有帮助,我可以看到mvn dependency:tree
中的依赖关系,但是在执行它时它没有添加到类路径中,例如通过mvn exec:java
也不会使用maven-jar-plugin
添加到清单中(但是maven-dependency-plugin:copy-dependencies
有效)
提出一个新问题,向我们展示您使用的代码是如何添加依赖项的。
已经有这样的问题(不是我的):***.com/questions/2065928/… 但是它不处理快照...除了这个详细的解决方案与我原来的解决方案相同。
我的“插件”是例如' exec:java
。另外,当您想知道如何添加依赖项时,为什么要发布 JAR 插件的配置?【参考方案2】:
Maven 永远不会读取存在于任何库文件夹中的 jar。您必须首先了解 maven 是如何工作的。 maven 查找 jar 的唯一位置是 localRepository (.m2)
,如果不存在,它会搜索您的 POM.xml
中提到的其他存储库
【讨论】:
我不是可以添加范围为系统的依赖项并添加文件路径并要求POM读取它吗? 但是由于 jar 已经存在于您的本地存储库中,它总是会在访问任何其他存储库之前找到它! 所以没有办法获取任何依赖的新快照? 是的,您必须将 jar 作为依赖项添加到您的项目中,并在构建项目之前构建 jar。您可以通过 parent/module 部分了解更多详细信息 虽然您的答案在技术上是正确的,但它并不真正适用于这里,因为 OP 已将 JAR 放在一个存储库中,而该存储库恰好位于他的项目结构中。 Maven 可以从那里读取它,但这里的关键问题是它只执行 一次。【参考方案3】:之前的回答者(和一位评论者)指出,maven 只在本地项目存储库中查找一次,在后续构建中,它会从 .m2 存储库中获取缓存的 jar。
我只是 found 解决需要增加版本号的方法(例如,在开发库的小改动上):
首先将 jar 重新安装到本地项目存储库中:
mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -DgroupId=com.johndoe.dev -DartifactId=Helpers -Dversion=0.1 -Dfile=C:/path/to/helpers.jar
(其中 -Dfile 可以指向生成 helpers.jar 的外部项目)
然后只清除 .m2-repository 中的这个特定工件:
mvn dependency:purge-local-repository -DmanualInclude=com.johndoe.dev:Helpers:0.1
(以com.johndoe.dev为GroupId,Helpers为ArtifactId,与上一步安装的版本相同)
执行后一步,maven 使用本地项目存储库 jar 文件重建 .m2 内的工件。
另一种可能是肮脏的变体: 只需将 helpers.jar 复制到 C:\Users\johndoe\.m2\repository\com\johndoe\dev\Helpers\0.1\Helpers-0.1.jar (不了解 linux,因为我没有在那里使用过 mave)。
【讨论】:
以上是关于Maven 3 不会从本地存储库更新快照依赖项的主要内容,如果未能解决你的问题,请参考以下文章
Maven:如何将本地 lib 目录用于依赖项而不是 Maven 存储库
Leiningen 中的本地依赖项而不创建 Maven 存储库?