Jim*_*son 30 java dependencies build-process maven-2 ivy
我们有一个大型(> 500,000 LOC)Java系统,它依赖于40-50个OSS包.系统使用Ant构建,目前手动处理依赖关系管理.我正在调查Ivy和/或Maven以自动化依赖关系.去年我们将Maven看作是一个构建自动化系统并拒绝它,因为它需要完全重构我们的系统以匹配Maven的架构.现在我正在寻求自动化依赖管理任务.
我已经对常春藤进行了一些实验,但遇到了问题.例如,当我将ActiveMQ指定为依赖项,并告诉Ivy使用Maven存储库中的POM进行依赖项规范时,Ivy检索了一堆我知道不需要的包(例如Jetty,Derby和Geronimo)使用ActiveMQ.
如果我在ivysettings.xml中设置usepoms ="false",它只获取activemq.jar,但这似乎打败了Ivy的目的,并将其降级为具有手动构建的依赖规范的简单jar-fetcher.
这里有一个更大的问题,在Windows中曾经被称为"DLL Hell".在某些情况下,两个直接的第一级依赖项将指向相同传递依赖项的不同版本(例如log4j.jar).只有一个log4j.jar可以在类路径中,因此依赖性解析涉及手动确定哪个版本与我们系统中的所有客户端兼容.
我想这一切都归结为每个包的依赖规范(POM)的质量.在ActiveMQ的情况下,没有范围声明,因此任何对ActiveMQ的引用都将下载其所有依赖项,除非我们手动排除我们不知道的那些依赖项.
在log4j的情况下,自动依赖性解析将要求所有log4j的客户端(依赖于log4j的其他包)对所有先前版本的log4j进行验证,并在POM中提供兼容的log4j版本的范围(或列表).这可能太多了.
这是目前的状况,还是我错过了什么?
Rob*_*anu 11
你这么说是对的
我想这一切都归结为每个包的依赖规范(POM)的质量.
我要添加的唯一内容是将POM或任何其他形式的元数据视为起点.它非常有用,例如ActiveMQ为您提供所有依赖项,但是您可以选择它是否确实适合您的项目.
毕竟,即使考虑到log4j版本,您是否有外部依赖选择版本或选择您知道适合您的版本?
至于你如何选择定制依赖关系,这里是你可以用常春藤做的:
Ivy检索了一堆我知道不需要使用ActiveMQ的软件包(例如Jetty,Derby和Geronimo).
这通常是因为应用程序中的模块性差.例如,应用程序的某些部分需要Jetty,但即使您不使用它,也最终会产生这种传递依赖性.
您可能想要查看常春藤排除机制:
<dependency name="A" rev="1.0">
<exclude module="B"/>
</dependency>
Run Code Online (Sandbox Code Playgroud)
只有一个log4j.jar可以在类路径中,因此依赖性解析涉及手动确定哪个版本与我们系统中的所有客户端兼容.
也许我误解了这一点,但是常春藤的冲突解决方案中没有手动元素.有一个默认冲突管理器列表:
如果需要,您可以提供自己的冲突管理器.
几乎就是这样.maven依赖系统(Ivy或多或少遵循)将它留给单个项目来做好为依赖项添加必要的元数据.大多数人没有.
如果你走这条路,期望花时间设置排除.
对于推荐OSGi的海报,OP表示他不愿意为Maven重新构建他的构建系统,我不认为他会想要重新构建他的应用程序以符合OSGi.此外,许多符合OSGi标准的OSS项目(并且没有您希望的那么多)具有与Maven相比更糟或更差的元数据
在您列出的依赖项中,以下内容optional
在activemq-core
pom 中定义(另请参阅Maven书中的相关部分).
我没有看到对Jetty的直接依赖,因此可能会从一个可选的依赖项中传递它.
在Maven中,可选的依赖项是自动处理的.基本上任何声明为可选的依赖项必须在您的pom中重新声明才能使用它.从上面链接的文档:
当不可能(无论出于什么原因)将项目拆分为子模块时,使用可选的依赖项.我们的想法是,某些依赖项仅用于项目中的某些功能,如果不使用该功能,则不需要.理想情况下,这样的功能将被拆分为一个依赖于核心功能项目的子模块......这个新的子项目只有非可选的依赖项,因为如果你决定使用子项目的功能,你需要它们.
但是,由于项目无法拆分(无论出于何种原因),因此这些依赖项被声明为可选项.如果用户想要使用与可选依赖项相关的功能,则必须在自己的项目中重新声明该可选依赖项.这不是处理这种情况最明确的方法,但是可选的依赖关系和依赖关系排除都是止损解决方案.
我不确定您是否可以配置Ivy来忽略可选的依赖项,但您可以将其配置为排除依赖项.例如:
<dependency name="A" rev="1.0">
<exclude module="B"/>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我知道这并不完全令人满意.可能是Ivy确实支持可选的依赖项(如果我发现任何内容,我会进一步查看和更新),但排除机制至少允许您管理它们.
关于你问题的最后部分.Maven将解析log4j的依赖版本,如果版本兼容,它将自动选择所列版本的"最近"版本.
从介绍到依赖机制:
依赖关系中介 - 确定在遇到工件的多个版本时将使用哪个版本的依赖关系.目前,Maven 2.0仅支持使用"最接近的定义",这意味着它将在依赖树中使用与项目最接近的依赖项版本.您可以通过在项目的POM中明确声明它来保证版本.请注意,如果两个依赖关系版本在依赖关系树中处于相同的深度,则直到Maven 2.0.8没有定义哪一个会赢,但是自Maven 2.0.9开始,它就是声明中的顺序:第一个声明获胜.
- "最接近的定义"表示所使用的版本将是依赖树中与项目最接近的版本,例如.如果A,B和C的依赖关系被定义为A - > B - > C - > D 2.0和A - > E - > D 1.0,则在构建A时将使用D 1.0,因为从A到D的路径是E更短.您可以在A中向D 2.0明确添加依赖项以强制使用D 2.0
如果版本不兼容,则问题比依赖项解决更大.我相信常春藤在类似的模型上运作,但我不是专家.
归档时间: |
|
查看次数: |
4331 次 |
最近记录: |