有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

编辑: 根据What exactly is a Maven Snapshot and why do we need it?,maven应尝试从不查找快照依赖项的版本,“即使在本地存储库中找到了此库的版本”。我的设置有什么问题

脏溶液: 根据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存储库中不可用时,该存储库工作)结合使用,并且第二部分在每次构建期间刷新.m2

但是,我仍然不清楚为什么普通的“快照”机制不起作用(即,当前脏解决方案在没有快照的情况下也会起作用,因为本地.m2repo每次都显式更新)。有没有更干净的办法

解决方案(基于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

将其部署到回购。正确部署后,maven将正确处理快照


共 (3) 个答案

  1. # 1 楼答案

    如果您为此使用存储库,那么Maven会将JAR复制一次到它的本地存储库中(通常在$HOME/.m2/repository/)。除非版本号改变,否则Maven不会认为这个文件发生了改变,它不会复制它。注意,版本号是Maven唯一关注的东西;它不关心校验和、文件大小或日期

    顺便说一句,快照在内部被分配了一个版本号,这样Maven就可以在内部注意到快照已经更新了

    我建议用system dependency代替。这样,实际的JAR将被添加到类路径中(没有任何复制或其他内容)。您也不需要为这种方法复制回购结构,它将清楚地传达您的意图

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

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

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

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

    2. 将依赖项安装到本地repo中;我建议为此使用一个脚本,您可以将其包含在项目中。这样,您就避免了所有问题,在新机器上设置这些问题也很容易

    3. 更改依赖项的版本号,但这很繁琐,而且当依赖项的实际版本号更改时,您可能会遇到麻烦

    4. 为您的公司设置本地repo服务器并将依赖项部署到该服务器。这将需要几个小时,但a)您将获得所有依赖项的本地缓存,从而加快初始构建速度;b)这将使其他开发人员的安装速度大大加快

  2. # 2 楼答案

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

  3. # 3 楼答案

    前面的回答者(和一位评论者)指出,maven只在本地项目存储库中查看一次,在后续构建中,它从数据库中获取缓存的jar。m2存储库

    我只是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存储库:

    mvn dependency:purge-local-repository -DmanualInclude=com.johndoe.dev:Helpers:0.1
    

    (以com.johndoe.dev作为GroupId,Helpers作为ArtifactId,并且与上一步中安装的版本相同)

    执行后一步,maven在内部重建工件。m2使用本地项目存储库jar文件

    可供选择的,可能是肮脏的变体: 只需复制助手。jar到C:\Users\johndoe\。m2\repository\com\johndoe\dev\Helpers\0.1\Helpers-0.1。jar(我不知道linux,因为我没有在那里使用过mave)