繁体   English   中英

Apache常春藤。 未检索传递依赖项

[英]Apache Ivy. Transitive dependencies not retrieved

我有以下结构的3个项目:

App
|  |
  ...
|  |
|  +--lib
|  |    |
|  |    +--...
|  |
|  +--dist
|
Lib
|  |
   ...
|  |
|  +--lib
|  |    |
|  |    +--sublib-1.0.jar
|  |
|  +--dist
|       |
|       +--lib-1.0.jar
|
SubLib
   |
  ... 
   |
   +--dist
        |
        +--sublib-1.0.jar

其中有以下关系:

App <-- Lib <-- SubLib

我正在使用apache ivy来检索AppLib的依赖项。 依赖关系描述如下: Lib ivy.xml

<ivy-module version = "2.0">
    <info organisation = "com.test.lib" module = "lib"/>
    <dependencies>
        <dependency org = "com.test.sub.lib" name = "sublib" rev = "1.0" conf = "compile->default"/>
    </dependencies>
</ivy-module>

App ivy.xml

<ivy-module version = "2.0">
    <info organisation = "com.test.app" module = "App"/>
    <dependencies>
        <dependency org = "com.test.lib" name = "lib" rev = "1.0" conf = "compile->default"/>
    </dependencies>
</ivy-module>

ivysettings.xml

<ivysettings>
    <settings defaultResolver = "local"/>    
    <resolvers>
        <filesystem name = "local">
            <artifact pattern = "${ivy.settings.dir}/SubLib/dist/[artifact]-[revision].[ext]"/>
            <artifact pattern = "${ivy.settings.dir}/Lib/dist/[artifact]-[revision].[ext]"/>
        </filesystem>
    </resolvers>    
    <modules>
        <module organisation = "com.test.ivytest" resolver = "local"/>
    </modules>
</ivysettings>

预期结果:执行ivy:retrievesublib-1.0.jarlib-1.0.jar都出现在App/lib

实际结果: App/lib只存在lib-1.0.jar 生成的ivy-report for App不包含任何提及subliblib的依赖项。 在构建期间,ant + ivy日志中没有任何类型。

注意: lib-1.0.jar不是作为fat-jar构建的。

我在这个配置中缺少什么?


更新

我做了一些思考,我得出的唯一结论是这个问题确实是错误的配置。 从事实来看,没有检索到传递依赖,我们可以肯定地说,当它解析lib时,常春藤没有任何类型的信息。 这是有道理的,因为Lib/dist文件夹可以在文件系统中的任何位置。 获得有关传递依赖的信息的唯一方法是在该jar附近的某个地方放置相应的ivy.xml 哪个不是。 日志[ivy:retrieve] local: no ivy file found for com.test.lib#lib;1.0: using default data的消息稍微证实了这一点[ivy:retrieve] local: no ivy file found for com.test.lib#lib;1.0: using default data 保留信息的唯一方法是%user%/.ivy/cache 生成的[org]-[artifact]-[conf].xml文件确实包含依赖项信息。 所以我猜这是为了正常工作,我将不得不在App的分辨率级别上使用缓存。

这有什么意义还是我明显错了?

好吧,问题确实是错误的配置和我对它的理解不足。 以下是如何使其工作的详细说明。 我的术语不是很好,所以我可能在这里误用了一些词。 让我们看一下项目配置以及它是什么。

Sublib将成为具有编译时依赖关系guava Lib运行时依赖项。

SubLib
   |  `lib
   |      `guava-19.0.jar
   |
    `dist
   |    `--sublib-1.0.jar
   |
    `src
        `...

因此,我们需要在SubLib的ivy.xml进行适当的配置:

<ivy-module version="2.0">
    <info organisation="com.test.sub.lib" module="sublib"/>

    <configurations>
        <conf name="runtime" visibility="public"/>
    </configurations>

    <dependencies>
        <dependency org="com.google" name="guava" rev="19.0" conf="runtime->default"/>
    </dependencies>
</ivy-module>

这里,通过声明runtime配置,我们声明此ivy.xml描述了一个运行时依赖的模块。 由于番石榴没有这样的文件,我们将其描述为默认值。 这里很标准。 现在,让其他人知道sublib-1.0.jar实际上有一个来自guava-19.0.jar的依赖,我们需要将它发布到一个存储库,以便这些信息以文件ivy-[version].xml形式存在于罐。 我选择发布到build文件夹。 为此, ivysettings.xml需要包含一个解析器,该解析器有助于匹配文件模式以便在我们从Lib解析时匹配文件模式。

<ivysettings>
    <settings defaultResolver="filesystem-resolver"/>

    <resolvers>
        <filesystem name="sublib-resolver">
            <ivy pattern="${ivy.settings.dir}/SubLib/dist/repo/ivy-[revision].xml"/>
            <artifact pattern="${ivy.settings.dir}/SubLib/dist/repo/[artifact]-[revision].[ext]"/>
        </filesystem>

        <filesystem name="filesystem-resolver">
            <artifact pattern="${ivy.settings.dir}/SubLib/lib/[artifact]-[revision].[ext]"/>
        </filesystem>
    </resolvers>

    <modules>
        <module name="sublib" organisation="com.test.sub.lib" resolver="sublib-resolver"/>
    </modules>
</ivysettings>

sublib-resolver将允许查找相应的ivy-[revision].xml ,其中包含有关jar的依赖关系和位置的信息。 filesystem-resolver将找到我们的guava依赖。 现在我们通过调用我们的解析器来发布带有antsublib

<target name="publish">
        <ivy:publish artifactspattern="${dist.dir}/[artifact]-[revision].[ext]"
                     resolver="sublib-resolver"
                     overwrite="true"
                     pubrevision="${revision}"
        />
</target>

现在到了Lib Lib将成为App编译时依赖项,我们在ivy.xml中将其描述为此类,并将SubLib声明为运行时依赖项

<ivy-module version="2.0">
    <info organisation="com.test.lib" module="lib"/>

    <configurations>
        <conf name="compile" visibility="public"/>
        <conf name="runtime" extends="compile" visibility="public"/>
    </configurations>

    <dependencies>
        <dependency org="com.test.sub.lib" name="sublib" rev="2.0" conf="runtime->compile"/>
    </dependencies>
</ivy-module>

这里是配置发挥作用的地方以及我最初不理解的地方。 runtime->compile左手边是可以理解的: sublib被声明为运行时依赖项,我们将它分配给runtime conf在它的常春藤文件中。 在箭头的右侧,我们声明我们也想要sublib的编译时依赖项。 而那样配置的就是guava 它将由解析器找到并检索。 所以,我们也需要一个Lib的解析器,所以完整的ivysettings.xml文件将如下所示:

<ivysettings>
    <properties file="${ivy.settings.dir}/ivysettings.properties"/>

    <settings defaultResolver="filesystem-resolver"/>

    <resolvers>
        <filesystem name="sublib-resolver">
            <ivy pattern="${ivy.settings.dir}/SubLib/dist/repo/ivy-[revision].xml"/>
            <artifact pattern="${ivy.settings.dir}/SubLib/dist/repo/[artifact]-[revision].[ext]"/>
        </filesystem>

        <filesystem name="lib-resolver">
            <ivy pattern="${ivy.settings.dir}/Lib/dist/repo/ivy-[revision].xml"/>
            <artifact pattern="${ivy.settings.dir}/Lib/dist/repo/[artifact]-[revision].[ext]"/>
        </filesystem>

        <filesystem name="filesystem-resolver">
            <artifact pattern="${ivy.settings.dir}/SubLib/lib/[artifact]-[revision].[ext]"/>
        </filesystem>
    </resolvers>

    <modules>
        <module name="sublib" organisation="com.test.sub.lib" resolver="sublib-resolver"/>
        <module name="lib" organisation="com.test.lib" resolver="lib-resolver"/>
    </modules>
</ivysettings>

并在Libbuild.xml发布Lib

<target name="publish">
        <ivy:publish artifactspattern="${dist.dir}/[artifact]-[revision].[ext]"
                     resolver="lib-resolver"
                     overwrite="true"
                     pubrevision="${revision}"
        />
</target>

现在主要问题是:传递检索。 配置。 Appivy.xml我们需要准确指出我们想要传递依赖。 存储在存储库中的信息是不够的。 必须在Appivy.xml指定它:

<configurations>
    <conf name="compile" visibility="public"/>
</configurations>

<dependencies>
    <dependency org="com.test.lib" name="lib" rev="1.0" conf="compile->compile; compile->runtime"/>
</dependencies>

这里发生的是:通过声明compile conf我们声明App有一个编译配置。 与之前一样,第一个箭头链表明我们(编译配置的模块App )想要获得名为lib编译配置依赖项。 分别为左右箭头两侧。 第二个箭头集指出我们(编译配置的模块App )想要获得运行时配置的lib依赖项 哪个是sublib 而且由于它与guava一起被检索出来。


一个有点凌乱的解释,可能不是最优雅的解决方案,但它是我设法使这项工作正常的唯一方法。 如果有人知道任何更好的方法,任何帮助将不胜感激。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM