阿帕奇常春藤。未检索到传递依赖项
Posted
技术标签:
【中文标题】阿帕奇常春藤。未检索到传递依赖项【英文标题】:Apache Ivy. Transitive dependencies not retrieved 【发布时间】:2017-02-23 15:28:56 【问题描述】:我有以下结构的 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 来检索 App
和 Lib
的依赖项。依赖关系描述如下:
ivy.xml
的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>
ivy.xml
的App
:
<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:retrieve
后,sublib-1.0.jar
和lib-1.0.jar
都会出现在App/lib
中
实际结果:只有lib-1.0.jar
出现在App/lib
中。为App
生成的常春藤报告不包含任何提及sublib
是lib
的依赖项。在构建期间,ant + ivy 日志中也没有任何内容。
注意: lib-1.0.jar
没有被构建为 fat-jar。
我在这个配置中缺少什么?
更新
我做了一些思考,得出的唯一结论是,这个问题确实是配置错误。从没有检索传递依赖的事实来看,我们可以肯定地说,ivy 在解析lib
时没有任何类型的信息。这是有道理的,因为Lib/dist
文件夹可能位于文件系统中的任何位置。获得有关传递依赖的信息的唯一方法是将各自的ivy.xml
放在靠近那个 jar 的某个地方。哪个不是。日志[ivy:retrieve] local: no ivy file found for com.test.lib#lib;1.0: using default data
中的消息略微证实了这一点。保留信息的唯一方法是在%user%/.ivy/cache
中缓存数据。那里生成的[org]-[artifact]-[conf].xml
文件确实包含依赖信息。所以我猜要让它正常工作,我必须在应用程序的分辨率级别上使用缓存。
这有什么意义吗?还是我又明显错了?
【问题讨论】:
ivy:resolve 应该在检索之前调用。你得到什么错误?是否有“配置缺失”之类的东西? 据我所知,没有必要。我看到日志中的[ivy:retrieve]
部分确实执行了解析。我没有收到任何错误,只是缺少传递的 jar 依赖项。
好的(也阅读更新的部分)可以请清除常春藤缓存并再次运行它。还将您用于发布 lib
和 sublib
的 ant 脚本添加到问题中。
ivy:cleancache
在App.clean
ant 任务期间被显式调用。只是没有提到。我目前正在测试一个想法,如果它工作正常,我会在这里发布。
你能显示你使用的完整的 ant 命令吗?
【参考方案1】:
好的,所以问题确实是错误的配置和我缺乏理解。这是如何使其工作的详细说明。我不太擅长术语,所以我可能在这里误用了一些词。让我们看看项目配置和什么。
Sublib
将成为Lib
的运行时 依赖项具有编译时 依赖项guava
。
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
描述了一个运行时依赖的模块。由于 guava 没有这样的文件,我们将其描述为默认文件。这里很标准。现在,为了让其他人知道sublib-1.0.jar
实际上具有来自guava-19.0.jar
的依赖关系,我们需要将其发布到存储库,以便此类信息以文件ivy-[version].xml
的形式存在于jar 旁边。我选择发布到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
依赖项。现在我们只需通过调用解析器来发布sublib
和ant
:
<target name="publish">
<ivy:publish artifactspattern="$dist.dir/[artifact]-[revision].[ext]"
resolver="sublib-resolver"
overwrite="true"
pubrevision="$revision"
/>
</target>
现在到Lib
。 Lib 将成为 App
的 compile-time 依赖项,我们在 ivy.xml
中对其进行描述,并将 SubLib
声明为它的 runtime 依赖项:
<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
被声明为运行时依赖项,我们将其分配给了 ivy 文件中的 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>
并在Lib
的build.xml
中发布Lib
:
<target name="publish">
<ivy:publish artifactspattern="$dist.dir/[artifact]-[revision].[ext]"
resolver="lib-resolver"
overwrite="true"
pubrevision="$revision"
/>
</target>
现在主要问题:及物检索。配置。在App
的ivy.xml
中,我们需要准确地指定我们想要传递依赖。它们存在存储在 repos 中的信息是不够的。必须在App
的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>
这里发生的情况如下:通过声明compile
conf,我们声明App
具有编译配置。第一个箭头链和之前一样,表明我们(编译配置模块App
)想要获得编译配置依赖项lib
。左右箭头边分别。第二个箭头表示我们(编译配置的模块App
)想要获得运行时配置的lib
的依赖关系!这是sublib
。由于它与guava
一起被检索到。
有点凌乱的解释,可能不是最优雅的解决方案,但这是我设法使其正常工作的唯一方法。如果有人知道这样做的更好方法,任何帮助将不胜感激。
【讨论】:
以上是关于阿帕奇常春藤。未检索到传递依赖项的主要内容,如果未能解决你的问题,请参考以下文章
我可以将 JSON 传递给这个 REST API 调用吗?阿帕奇点燃