在Maven中使用自定义远程存储库时出现奇怪的行为

时间:2011-12-15 01:45:21

标签: java maven

我只是想了解使用Maven定制远程存储库背后的逻辑。在一个实验中(在OS X中,使用命令行)我在这样的POM中声明一个远程存储库:(实际上并不是真正的远程,因为我使用的是file:/// ...):

<repositories>
    <repository>
      <id>myRepository</id>
      <url>file:///test_mvrepository/repository</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
</repositories>

此POM还声明了对某些工件X(在我的示例中为JPL库)的依赖性,该工件仅存在于“远程”存储库中,而不存在于本地存储库中:

<dependencies>
    <dependency>
        <groupId>jpl</groupId>
        <artifactId>jpl</artifactId>
        <version>[3.1.4-alpha,]</version>
    </dependency>
    ...
</dependencies>

执行此操作时:

mvn package

项目按预期构建仅一次。如果我重复操作,我会收到一条消息,说我的工件X无法访问:

[ERROR] Failed to execute goal on project projectname: Could not resolve dependencies for project groupid:artifactid:jar:0.0.1-SNAPSHOT: Could not find artifact jpl:jpl:jar:3.1.4-alpha -> [Help 1]

这是完整的POM:

<?xml version="1.0" encoding="UTF-8"?>
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>groupId</groupId>
  <artifactId>artifactId</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <repositories>
    <repository>
      <id>repId</id>
      <url>file:///test_mvrepository/repository</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
  </repositories>
  <dependencies>
    <dependency>
        <groupId>jpl</groupId>
        <artifactId>jpl</artifactId>
        <version>[3.1.4-alpha,]</version>
    </dependency>
    ...
  </dependencies>

</project>

经过一些调试我发现虽然我没有用mvn install安装POM,但是工件X在本地存储库(它的POM,jar和其他文件)中。只有当我从本地存储库中删除该条目时,我才能再次重复该操作而不会收到错误消息。 实际上,我不必删除本地存储库中的所有条目,只删除文件maven-metadata-local.xml。这是这个文件的样子:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>jpl</groupId>
  <artifactId>jpl</artifactId>
  <versioning>
    <release>3.1.4-alpha</release>
    <versions>
      <version>3.1.4-alpha</version>
    </versions>
    <lastUpdated>20111214230431</lastUpdated>
  </versioning>

在我的远程存储库中,该文件名为maven-metadata.xml

最后,如果我输入

mvn install

然后,X始终可以按预期访问,而不仅仅是前一种情况下的一次。

我无法理解这个的逻辑。为什么我不能让Maven在这个环境中多次打包我的神器?对我来说很明显,如果我没有将它安装在本地存储库中,那么它应该一次又一次地进入远程存储库。或者至少,它应该以一种我以后可以引用它们的方式在本地存储库中安装必要的对象,而不是阻止所有未来的package请求,直到我手动删除该条目?这是Maven中的错误吗?谢谢你的任何澄清!

更新 如果它很重要,这就是我构建测试场景的方式:

  • 我在我的本地存储库中安装了JPL库(它的依赖是给我带来问题的那个)。我用这个命令做到了:

    mvn install:install-file -Dfile = jpl.jar -DgroupId = jpl -DartifactId = jpl -Dversion = 3.1.4-alpha -Dpackaging = jar

  • 我将本地存储库复制到文件系统中的新位置(我的“远程”存储库),在这个新位置,我将JPL条目的maven-metadata-local.xml的名称更改为{ {1}},如下所述:http://www.javaworld.com/community/node/3968

  • 我从本地存储库中删除了JPL条目。

2 个答案:

答案 0 :(得分:2)

如果要创建远程存储库来保存工件,则必须使用deploy阶段而不是install阶段将工件上传到工作站。

install阶段将您的工件上传到local存储库,默认情况下位于~/.m2/{USER.HOME}/.m2/下。您的本地存储库只是远程存储库的缓存。

deploy阶段使用pom文件中提供的distributionManagement信息将工件部署到远程存储库。您可以这样创建distributionManagement定义:

<distributionManagement>
  <repository>
    <id>SomeId</id>
    <name>SomeName</name>
    <url>file:///test_mvrepository/repository</url>
  </repository>
</distributionManagement>

有关分发管理的进一步参考,请参阅此site

由于您已在repositories定义中引用了远程存储库,因此当您将工件部署到远程存储库一次时,它们将在您将来的构建期间被提取并缓存到本地存储库中。

您可以考虑详细了解有关repositoriesmaven lifecycles的信息。在SO上还有一些类似的问题得到了很好的回答herehere

答案 1 :(得分:1)

mvn install当前项目添加到本地存储库。当您调用任何 Maven目标或阶段时,依赖关系会缓存在本地存储库中。因此,无论您使用何种阶段,您总是希望X最终在本地存储库中。

然而,你所看到的行为很奇怪。文件权限有问题吗?你能否更新帖子第二次运行mvn package时得到的确切错误?

修改

好吧我怀疑m2e发生了一些奇怪的事情。使用命令行时是否会发生此行为?

您可以尝试将copy-dependencies插件绑定到包中吗?这应该可以防止m2e在Eclipse中做出奇怪的事情。