Maven 3不会从本地存储库更新快照依赖项

时间:2014-02-25 13:30:34

标签: java maven

我正在尝试在我的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(没有更新版本号,因为它只是另一个快照)时,不使用此更新的jar(而是使用.m2目录中的旧版本)即使是mvn -U clean install 如何让maven更新这个jar?

修改: 根据{{​​3}} maven将尝试找到从不版本的SNAPSHOT依赖,“即使在本地存储库中找到该库的一个版本”。我的设置有什么问题?

DIRTY SOLUTION : 根据{{​​3}}的回答,我的原始解决方案的扩展似乎有效:

        <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存储库中不可用时工作)和第二个工作结合使用部件在每次构建期间刷新.m2

然而,我仍然不清楚为什么普通的“SNAPSHOT”机制不起作用(即当前的脏解决方案也可以在没有SNAPSHOT的情况下工作,因为每次都明确更新本地.m2 repo)。有没有更清洁的方式?

解决方案(基于Aaron的回答和讨论):问题是我尝试使用libRepo将文件安装到install-file。实际的解决方案是,如果库更新,请使用

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。

3 个答案:

答案 0 :(得分:5)

如果您使用存储库,那么Maven会将JAR复制到其本地存储库(通常在$HOME/.m2/repository/中)。除非版本号更改,否则Maven不会认为此文件已更改,也不会复制它。请注意,版本号是Maven唯一看到的内容;它不关心校验和或文件大小或日期。

顺便提一下,为此目的在内部为快照分配了一个版本号:这样Maven就可以在内部注意到快照已经更新。

我建议改用system dependency。这样,实际的JAR将被添加到类路径中(没有任何复制或东西)。您也不需要复制此方法的repo结构,它将清楚地传达您的意图。

[编辑] 我知道Maven以不同的方式处理范围system的依赖关系。我不确定这是否有意义(如果它使用依赖项进行编译,它肯定可以用它来运行?)

在我看来,你有以下选择:

  1. 使用deploy:deploy-file将相关性安装到libRepo,而不是自行复制。这应该以这样的方式更新元数据:当您在真实项目上再次运行mvn install时,Maven将再次复制它。

    请注意,file:install不起作用。文件插件用于访问本地存储库,但您需要使用知道如何更新共享/服务器存储库的deploy插件。

  2. 将依赖项安装到本地存储库中;我建议使用一个脚本,你可以包含在你的项目中。这样,您可以避免所有问题,并且可以轻松地在新机器上进行设置。

  3. 更改依赖项的版本号,但这很乏味,当依赖项的实际版本号发生变化时,您可能会遇到麻烦。

  4. 为您的公司设置本地仓库服务器并将依赖关系部署到该公司。这将花费几个小时,但a)您将获得所有依赖项的本地缓存,使您的初始构建更快,b)它将更快地为其他开发人员设置。

答案 1 :(得分:1)

Maven永远不会读取任何库文件夹中的jar。你必须首先了解maven是如何工作的。 maven查找jar的唯一地方是localRepository (.m2),如果没有,则会搜索POM.xml

中提到的其他存储库

答案 2 :(得分:0)

前面的回答者(和一个评论者)指出,maven只在本地项目库中查找一次,在后续版本中,它从.m2-repository获取缓存的jar。

我只是found一个解决方法,需要增加版本号(例如,对dev-library的小改动):

首先将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)。