【问题标题】:Simplest Ivy code to programmatically retrieve dependency from Maven Central以编程方式从 Maven 中心检索依赖项的最简单的 Ivy 代码
【发布时间】:2013-03-13 23:28:49
【问题描述】:

我发现 Ivy API 非常复杂。

使用 Ivy 100% 以编程方式(没有 Ant,没有 Xml 文件,...)从 Maven Central 将工件检索到特定本地目录中的最简单的 sn-p 是什么?

举例来说,将 commons-logging:commons-logging:1.1:jar 检索到 /my/destination 中。

【问题讨论】:

  • 为什么要求常春藤?其他库/代码 sn-ps 可以接受吗?
  • 当然,如果您有替代解决方案可以在本地缓存并确保下载不会损坏,那也没关系。
  • 我本来打算推荐Aether,但后来我看了他们的examplesAPI,才明白为什么人们取笑Java程序员。
  • 如果您确实需要本地缓存,我建议改编 Maven Ant 任务中的 Dependencies 任务。虽然这需要的代码比我想写的要多,但它看起来非常简单(如果您过去没有开发过 Ant 任务,请从 DependenciesTask.javadoExecuteResolution() 方法开始)。代码看起来很简单,但您必须构建一个内存中的 Maven POM。
  • 我们这里有一个本地构建系统(我继承了它),并以编程方式使用 Ivy。你是对的,复杂的,没有记录的。我一辈子都不知道如何让它下载源代码和编译后的代码。

标签: java ivy


【解决方案1】:

我一直致力于使用 Ivy 从 Maven 存储库中远程解析工件(和依赖项)。这是一个下载一个工件(无依赖项)的代码示例。

如果需要依赖,需要适配依赖描述符。

一些注意事项:

  1. Ivy 使用缓存来存储以前检索到的工件及其“ivy 翻译”(您会在缓存中找到源自 Maven 工件的 ivy 模块)

  2. 一般概念是您以编程方式创建一个 Ivy 模块,该模块依赖于存储“伪模块”的 Maven 存储库(即,解析器实现了底层映射 - 我相信)。

  3. 一般来说一个很好的起点,如果你想知道如何以编程方式使用 Ivy,主类是org.apache.ivy.Main


        public static void main(String[] args) throws Exception {

        String groupId = "org.springframework";
        String artifactId = "spring-context-support";
        String version = "4.0.2.RELEASE";
        File   out = new File("out");

        // create an ivy instance
        IvySettings ivySettings = new IvySettings();
        ivySettings.setDefaultCache(new File("ivy/cache"));

        // use the biblio resolver, if you consider resolving 
        // POM declared dependencies
        IBiblioResolver br = new IBiblioResolver();
        br.setM2compatible(true);
        br.setUsepoms(true);
        br.setName("central");

        ivySettings.addResolver(br);
        ivySettings.setDefaultResolver(br.getName());

        Ivy ivy = Ivy.newInstance(ivySettings);

        // Step 1: you always need to resolve before you can retrieve
        //
        ResolveOptions ro = new ResolveOptions();
        // this seems to have no impact, if you resolve by module descriptor (in contrast to resolve by ModuleRevisionId)
        ro.setTransitive(true);
        // if set to false, nothing will be downloaded
        ro.setDownload(true);

        // 1st create an ivy module (this always(!) has a "default" configuration already)
        DefaultModuleDescriptor md = DefaultModuleDescriptor.newDefaultInstance(
            // give it some related name (so it can be cached)
            ModuleRevisionId.newInstance(
                groupId, 
                artifactId+"-envelope", 
                version
            )
        );

        // 2. add dependencies for what we are really looking for
        ModuleRevisionId ri = ModuleRevisionId.newInstance(
            groupId, 
            artifactId,
            version
        );
        // don't go transitive here, if you want the single artifact
        DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md, ri, false, false, false);

        // map to master to just get the code jar. See generated ivy module xmls from maven repo
        // on how configurations are mapped into ivy. Or check 
        // e.g. http://lightguard-jp.blogspot.de/2009/04/ivy-configurations-when-pulling-from.html
        dd.addDependencyConfiguration("default", "master");
        md.addDependency(dd);

        // now resolve
        ResolveReport rr = ivy.resolve(md,ro);
        if (rr.hasError()) {
            throw new RuntimeException(rr.getAllProblemMessages().toString());
        }

        // Step 2: retrieve
        ModuleDescriptor m = rr.getModuleDescriptor();

        ivy.retrieve(
            m.getModuleRevisionId(),
            out.getAbsolutePath()+"/[artifact](-[classifier]).[ext]",
            new RetrieveOptions()
                // this is from the envelop module
                .setConfs(new String[]{"default"})
        );
    }

【讨论】:

  • 我们如何让它同时下载组/工件/版本的源代码?
  • ResolveOptionstransitivedownload 标志具有默认值 true,因此无需调用它们的设置器。
  • 如何将凭据添加到您的 ivy 设置中?
  • 抱歉,无法回答这些问题。我们继续使用 eclipse aether 进行远程 maven repo 访问。不记得确切原因,但常春藤中严重缺少某些东西(当然现在可能已经改变了)。
  • 我可以使用 CredentialsStore 传递凭证。 CredentialsStore.INSTANCE.addCredentials(null, host, username, password)
【解决方案2】:

检索工件(及其依赖项)的最简单方法是 use ivy from the command-line

java -jar ivy.jar -dependency commons-logging commons-logging 1.1 -retrieve "/my/destination/[artifact](-[classifier]).[ext]"

这会将文件检索到目录“/my/destination”中。

其他例子:

【讨论】:

  • 这有点延伸了“100% 以编程方式”,因为它完全避免了 API。
  • @AxelFontaine 完成工作 :-) 如果您遵循第一个示例列表,我确实有一个调用 ivy 任务的 groovy 示例。就我个人而言,我从来不需要使用 ivy 的 Java API。正如大卫所说,无论如何它都没有很好的记录。
猜你喜欢
  • 2021-03-24
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 2014-07-11
  • 1970-01-01
  • 2015-02-03
  • 2015-04-22
  • 1970-01-01
相关资源
最近更新 更多