问题 以编程方式获取Maven工件[关闭]


我正在寻找一个Java API,可用于从远程存储库中检索Maven工件。我发现了 Eclipse Ather 到目前为止,它看起来很复杂,因为我的需求,所以我正在寻找更简单的东西。

我需要的是:

  • 我必须指定远程Maven存储库的位置
  • 我喜欢基于它的groupId + artifactId +版本来获取工件
  • API必须提供工件的当前远程版本(考虑定期构建的SNAPSHOT工件,以便它们在其版本中具有生成的部分)
  • 返回工件的位置,首选HTTP URL(我将使用例如Apache HTTP Client自己获取它)
  • 可选地,检索作为所请求的工件的依赖项的工件。

8799
2018-05-10 14:30


起源

听起来你试图用Aether库重新发明轮子。所以我会深入研究Aether lib,可能会在他们的邮件列表上询问是否存在使用不同的神器解析器(稍后下载等)的可能性。我怀疑,但只是尝试一下。 - khmarbaise
我试一试。 - NagyI
这里列出了一些常春藤选项: stackoverflow.com/questions/3955209/... - Mark O'Connor


答案:


jcabi,乙醚 可以帮到你(我是开发人员)。它是Aether的简单包装器,可以让您找到Maven工件的所有传递依赖项:

File repo = this.session.getLocalRepository().getBasedir();
Collection<Artifact> deps = new Aether(this.getProject(), repo).resolve(
  new DefaultArtifact("junit", "junit-dep", "", "jar", "4.10"),
  JavaScopes.RUNTIME
);

因此,您需要提供的所有内容是:

  • 本地仓库位置,作为目录名称
  • 存储库列表(MavenProject#getRemoteRepositories()
  • 神器的Maven坐标
  • Maven范围寻找

找到的每个依赖项的绝对路径都可以获得 Artifact#getPath()


9
2018-05-20 08:01



我接受这个,因为它看起来像我最需要的东西,似乎很容易使用。 - NagyI
谢谢你的伟大项目。我发现它在测试maven插件时很有用(模拟检索工件的行为)。 - Gábor Lipták
随意在Github上加星: github.com/jcabi/jcabi-aether/stargazers :) - yegor256


    public List<Artifact> findDependencies(Artifact artifact) throws DependencyCollectionException {

    CollectRequest collectRequest = new CollectRequest();
    collectRequest.setRoot( new Dependency(artifact, "" ) );
    collectRequest.addRepository(repository);

    final MavenServiceLocator locator = new MavenServiceLocator();
    locator.addService( RepositoryConnectorFactory.class, FileRepositoryConnectorFactory.class );
    locator.addService( RepositoryConnectorFactory.class, WagonRepositoryConnectorFactory.class );
    locator.setServices( WagonProvider.class, new WagonProvider() {
        public Wagon lookup(String roleHint) throws Exception {
            if (Arrays.asList("http", "https").contains(roleHint)) {
                return new LightweightHttpWagon();
            }
            return null;
        }

        public void release(Wagon wagon) {

        }
    });

    final RepositorySystem system = locator.getService(RepositorySystem.class);
    MavenRepositorySystemSession session = new MavenRepositorySystemSession();

    session.setLocalRepositoryManager( system.newLocalRepositoryManager(localRepository) );
    session.setTransferListener( new LoggingTransferListener() );
    session.setRepositoryListener( new LoggingRepositoryListener() );

    final List<Artifact> artifacts = new ArrayList<Artifact>();

    system.collectDependencies(session, collectRequest).getRoot().accept( new DependencyVisitor() {
        public boolean visitEnter(DependencyNode dependencyNode) {
            artifacts.add(dependencyNode.getDependency().getArtifact());
            return true;
        }

        public boolean visitLeave(DependencyNode dependencyNode) {
            return true;
        }
    });
    return artifacts;
}

1
2018-03-04 17:38



你能否建议如何使用更新的Maven和Eclipse Aether? - wilx


以太开玩笑实际上是非常简单而优雅的做法。这是Maven 3中的一个主要增强功能,许多人都在寻找它。看着 这个 一些初始代码可以使用。我不记得获取工件的确切URL的方法,但AFAIR支持其他要求。


0
2018-05-10 15:01



我不喜欢使用Aether的一个问题是我必须创建一个临时存储库,只是为了获取它的工件。我不希望Aether下载该文件。我只是想知道哪个是神器的最新版本以及它在网络上的位置。想象一下,我有一个应用程序分发zip,没有任何依赖的工件,所以它只是独自站立。我可以自己轻松取出,甚至可以在下载时更好地解压缩。 - NagyI
@Michal Kalinowski,你给出的例子展示了如何在maven插件中使用Aether。您是否知道任何展示如何在常规(非插件)Java程序中使用它的文档? - user944849


你尝试过使用过吗? Apache常春藤?它支持获取maven依赖项。

这个用例的文档有点稀疏,但我发现了一些有关Ivy程序化使用的信息 这里


0
2018-05-10 15:07



这不是绝对的程序化。它需要预定义的XML文件,这些文件定义了依赖关系和其他配置。如果在执行期间动态确定(从外部源获取)会怎么样?我不喜欢到处都有临时文件。 - NagyI
我认为您可能需要这些文件来确定远程仓库位置,但希望您不需要使用配置文件来检索特定的依赖项。 Gradle和SBT使用常春藤来获取依赖关系,我认为他们没有xml配置文件。 - Sean Reilly
我懂了。我会更深入地了解Ivy。谢谢! - NagyI