如何避免使用 Ivy 复制依赖项

Posted

技术标签:

【中文标题】如何避免使用 Ivy 复制依赖项【英文标题】:How to avoid copying dependencies with Ivy 【发布时间】:2011-02-06 06:11:19 【问题描述】:

我正在研究使用 Ivy 来管理依赖项,但是哇——这东西真的很喜欢制作 jar 的多个副本!它像我后院的常春藤一样蔓延,同样不受欢迎!

是否可以让 Ivy 简单地定义一个引用已解析依赖项的类路径(用于指定的配置文件),以便我的 javac 可以直接在 ivy 存储库(或缓存?)中引用它们。

我已阅读参考文档,仅购买了设置符号链接到存储库缓存的选项。我想这已经足够了,但这似乎是一种浪费。另外,我不确定“战争”任务是否可以从符号链接构建战争......但我想我会在尝试时发现。

有更好的建议吗?

【问题讨论】:

【参考方案1】:

在与写得很糟糕的 Ivy 文档作斗争之后(叹气 - 这些人有什么问题? - 他们没有参加任何语言的高中识字课吗?),我看到有一个名为 的解决后任务cachepath 将构造一个指向已解析依赖项工件的 ant 路径,而不是将文件复制到 lib 目录。这可能正是我想要的!

【讨论】:

我放弃了! Ivy 的文档太糟糕了,它使整个框架变得毫无用处。我将不得不编写自己的依赖管理构建配置。 成为解决方案并为常春藤创建更好的文档不是更好吗?与整个部门管理系统相比,这似乎更难维护【参考方案2】:

这是我的标准 Java 构建文件,它创建了一个可执行文件 jar

我们的目标是通过 ANT 属性和 ivy.xml 文件的组合来管理项目特定的东西以用于第 3 方依赖项。

<project xmlns:ivy="antlib:org.apache.ivy.ant" name="demo" default="build">

  <property name="src.dir" location="src"/>
  <property name="build.dir" location="build"/>
  <property name="dist.dir" location="dist"/>
  <property name="dist.jar" location="$dist.dir/$ant.project.name.jar"/>
  <property name="dist.main.class" value="HelloWorld"/>

  <target name="retrieve">
    <ivy:resolve/>
    <ivy:cachepath pathid="build.path" conf="build"/>
    <ivy:cachepath pathid="runtime.path" conf="runtime"/>
  </target>

  <target name="compile" depends="retrieve">
    <mkdir dir="$build.dir/classes"/>
    <javac srcdir="$src.dir" destdir="$build.dir/classes" classpathref="build.path"/>
  </target>

  <target name="build" depends="compile">
    <ivy:retrieve pattern="$dist.dir/lib/[artifact].[ext]"/>

    <manifestclasspath property="jar.classpath" jarfile="$dist.jar">
      <classpath>
        <fileset dir="$dist.dir/lib" includes="*.jar"/>
      </classpath>
    </manifestclasspath>

    <jar destfile="$dist.jar" basedir="$build.dir/classes">
      <manifest>
        <attribute name="Main-Class" value="$dist.main.class"/>
        <attribute name="Class-Path" value="$jar.classpath"/>
      </manifest>
    </jar>
  </target>

  <target name="clean">
    <delete dir="$build.dir"/>
    <delete dir="$dist.dir"/>
  </target>

</project>

正如您在 Ivy 文档中发现的那样,cachepath Ivy 任务用于管理两条 ANT 路径。一个用于构建依赖项,另一个用于可执行文件jar 的运行时依赖项。

Ivy 的真正力量在于configurations。我发现最初很难掌握,直到我意识到这是一个简单的 jars 逻辑分组,我可以为我的项目定义。这个例子有两个configurations

build runtime

这里是 ivy 文件,展示了如何将依赖项与 configurations 关联:

<ivy-module version="2.0">
    <info organisation="com.myspotontheweb" module="demo"/>
    <configurations>
        <conf name="build" description="Libraries needed to for compilation"/>
        <conf name="runtime" extends="build" description="Libraries that need to be included with project jar" />
    </configurations>
    <dependencies>
        <dependency org="commons-lang" name="commons-lang" rev="2.0" conf="build->default"/>
        <dependency org="commons-cli" name="commons-cli" rev="1.0" conf="runtime->default"/>
    </dependencies>
</ivy-module>

最后,我希望这个例子有助于理解 Ivy。我喜欢它只专注于一件事的方式,即管理 3rd 方依赖项。

【讨论】:

详细且写得很好。谢谢,这很有帮助。 请注意,可能需要使用type="jar" 限制cachepath,并且缓存路径也可以直接用于打包:***.com/a/19220826/603516 @Vadzim 我从未见过需要限制配置。通常配置映射(到远程“默认”配置)可以很好地确保只包含 jar 工件。【参考方案3】:

只是为了补充@Mark 的答案。

注意cachepath的结果也可以直接用在构建中,不需要用retrieve复制jar:

<target name="build" depends="compile">
    <jar destfile="$dist.ear">
        <mappedresources>
            <resources refid="runtime.path"/>
            <chainedmapper>
                <flattenmapper/>
                <globmapper from="*" to="lib/*"/>
            </chainedmapper>
        </mappedresources>
    </jar>
</target>

【讨论】:

+1 聪明的主意。过去我通过首先使用 ivy 检索任务创建临时暂存目录以构建 WAR 或 EAR 文件来完成此操作。 @Mark,请您分享对***.com/questions/19227004/… 的任何想法好吗? 我看到了,但不知道有什么方法可以轻松地从 ivy 配置中减去依赖项。

以上是关于如何避免使用 Ivy 复制依赖项的主要内容,如果未能解决你的问题,请参考以下文章

从命令行使用时,如何让 Ivy 将依赖项复制到 lib 目录?

Grails:使用快照依赖项离线工作

在 WAR 文件中排除 Ivy 依赖项

如何使用 Ant 和 Ivy 构建项目及其依赖项

如何使用不同的分类器在 Ivy 中下载多个 Maven 依赖项?

如何使用 Sonatype Nexus 作为 Ivy 依赖项的镜像 [重复]