java/maven如何在运行时解决依赖项冲突 [英] How java/maven resolves dependency conflicts at run time

查看:198
本文介绍了java/maven如何在运行时解决依赖项冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起,我的新手问题.

Sorry for my newbie question.

假设我有一个包A,例如,在其maven文件中将B,C声明为其依赖项. B,C使用log4j的两个不同版本进行记录.我有几个问题:

Supposedly I have a package A which declares B, C as its dependencies in its maven files for example. B, C use two different versions of log4j for logging. I have a couple of questions:

  1. 如果我使用maven,并声明B,C为A的依赖项.当maven从mavencentral存储库中提取B,C的工件(.jar)时. B,C jar文件是否包含log4j类文件或仅包含它们自己的编译文件(B,C自己的源代码,而不是依赖项).
  2. 如果我正确理解,那么在构建发生时,最后,构建中将只有一个log4j类文件(即使B,C使用不同版本的log4j).选择要在此处构建哪个版本的log4j?这是否意味着我也需要将log4j声明为A依赖项(在A的maven构建文件中)-并且将选择要构建的版本.
  3. B,C可能使用完全不同的log4j版本. API可能会完全不同.它在运行时应该引起问题吗?但是实际上,这是非常罕见的吗?为什么这样?

谢谢.

推荐答案

  1. jar文件通常不包含其依赖项.有一种方法可以做到这一点,称为肥罐. 什么是胖JAR?,但假设您使用的是常规jar依赖项.罐子只会在自己的pom.xml中声明其依赖项.因此,在您的示例中,B和C将仅包含它们自己的已编译源代码.

  1. jar files usually do not contain their dependencies. There is a way to do this called fat jar. What is a fat JAR? but let's assume you are using regular jar dependencies. The jars will only declare their dependencies in their own pom.xml. So for your example, B and C will contain only their own compiled source code.

这实际上取决于您打包文件的方式.通常,如果仅生成一个简单的jar,它将不包含依赖项,运行程序负责提供正确的依赖项.例如,如果发生战争,maven将抛出所有依赖项.前面提到的另一种方法是胖子罐.一种更常见的方法是压缩所有依赖项并分别提供它们.

It really depends on how you pack the files. In general, if you only generate a simple jar, it will not contain the dependencies, and it is the responsibility of the runner to supply the correct dependencies. In case of a war, for example, maven will throw in all dependencies. Another way as mentioned before is fat jar. One more common way is to zip all the dependencies and supply them separately.

我不知道您为什么以前没有遇到冲突,但是对于其他许多库,我都不记得log4j的情况.作为库维护者,一种处理此类冲突的方法是,当您进行非向后兼容更改时,要更改程序包名称,这样用户可以在类路径中安全地拥有多个版本(无论如何应避免使用).

I do not know why you have not encountered a conflict before, I have, with many other libraries, I do not remember a case with log4j though. One way to handle these kind of conflicts, as a library maintainer, is when you make a non backward compatible change, to change the package name, this way the user can safely have multiple versions in the classpath (which should be avoided anyway).

Maven有一种避免此类冲突的方法,它将优先考虑最接近的已定义依赖项版本.例如,如果您在A中声明了版本a,在B中声明了版本b,则有效版本将为A.

Maven has a way to avoid these kind of conflict, it will give priority to the closest defined dependency version. For example, if you have version a declared in A and version b in B, then the effective version will be A.

此外,还有其他一些机制,例如依赖性管理.您可以在此处查看: https://maven.apache.org /guides/introduction/introduction-to-dependency-mechanism.html

Also, there are some other mechanisms like dependency management. You can look here: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

此主题非常严重,可能会导致很多难以发现的生产错误.希望这对您有帮助...

This topic is a very serious and may cause a lot of hard to detect production errors. Hope this helps...

这篇关于java/maven如何在运行时解决依赖项冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆