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

Hig*_*tor 9 java ant ivy dependency-management

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

App
|  |
  ...
|  |
|  +--lib
|  |    |
|  |    +--...
|  |
|  +--dist
|
Lib
|  |
   ...
|  |
|  +--lib
|  |    |
|  |    +--sublib-1.0.jar
|  |
|  +--dist
|       |
|       +--lib-1.0.jar
|
SubLib
   |
  ... 
   |
   +--dist
        |
        +--sublib-1.0.jar
Run Code Online (Sandbox Code Playgroud)

其中有以下关系:

App <-- Lib <-- SubLib
Run Code Online (Sandbox Code Playgroud)

我使用的Apache常春藤检索都依赖AppLib.依赖关系描述如下: ivy.xmlof Lib:

<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>
Run Code Online (Sandbox Code Playgroud)

ivy.xmlApp:

<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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

预期结果:执行后ivy:retrieve,既sublib-1.0.jarlib-1.0.jar存在于App/lib

实际结果:仅存lib-1.0.jar在于App/lib.生成的常春藤报告App中没有提到任何sublib依赖性lib.在构建期间,ant + ivy日志中没有任何类型.

注意: lib-1.0.jar不是作为胖罐建造的.

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


更新

我做了一些思考,我得出的唯一结论是这个问题确实是错误的配置.从事实来看,没有检索到传递依赖,我们可以肯定地说,常春藤在结算时没有任何类型的信息lib.这是有道理的,因为Lib/dist文件夹可以在文件系统中的任何位置.获得有关传递依赖的信息的唯一方法是分别ivy.xml靠近那个罐子.哪个不是.日志中的消息稍微确认了这一点[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的分辨率级别上使用缓存.

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

Hig*_*tor 2

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

Sublib将成为运行时依赖,因为Lib 它具有编译时依赖guava

SubLib
   |  `lib
   |      `guava-19.0.jar
   |
    `dist
   |    `--sublib-1.0.jar
   |
    `src
        `...
Run Code Online (Sandbox Code Playgroud)

所以,我们需要在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>
Run Code Online (Sandbox Code Playgroud)

在这里,通过声明runtime配置,我们声明它ivy.xml描述了一个运行时依赖项的模块。由于番石榴没有这样的文件,我们将其描述为默认文件。这里相当标准。现在,为了让其他人知道它sublib-1.0.jar实际上具有依赖关系,guava-19.0.jar我们需要将其发布到存储库,以便此类信息以文件形式存在于ivy-[version].xmljar 旁边。我选择发布到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>
Run Code Online (Sandbox Code Playgroud)

sublib-resolver将允许找到ivy-[revision].xml具有有关依赖项和位置信息的对应项jar。而filesystem-resolver会发现我们的guava依赖。现在我们只需通过调用我们的解析器sublib来发布:ant

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

现在到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>
Run Code Online (Sandbox Code Playgroud)

这就是配置发挥作用的地方,也是我一开始不明白的地方。runtime->compile左侧是可以理解的:sublib被声明为运行时依赖项,我们将其分配给runtime它的 ivy 文件中的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>
Run Code Online (Sandbox Code Playgroud)

Lib并在Lib中发布build.xml

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

现在主要问题:传递检索。配置。在 中Appivy.xml我们需要准确指定我们想要传递依赖。它们存储在存储库中的信息是不够的。必须在Apps中指定它ivy.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>
Run Code Online (Sandbox Code Playgroud)

这里发生的情况如下:通过声明compileconf,我们声明它App具有编译配置。第一个箭头链与之前一样,表明我们(编译配置的模块App)想要获得名为 的编译配置依赖项lib。分别为左、右箭头侧。第二个箭头集表明我们(编译配置的模块App)想要获得运行时配置的依赖项lib!这是sublib. 由于它与guava它一起出现,因此也被检索。


有点混乱的解释,可能不是解决方案中最优雅的解释,但这是我设法使其正常工作的唯一方法。如果有人知道更好的方法,我们将不胜感激。