- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
转载请注明出处:
Jar包冲突往往是很诡异的事情,也很难排查,但也会有一些共性的表现.
抛出java.lang.ClassNotFoundException:典型异常,主要是依赖中没有该类。导致原因有两方面:第一,的确没有引入该类;第二,由于Jar包冲突,Maven仲裁机制选择了错误的版本,导致加载的Jar包中没有该类.
抛出java.lang.NoSuchMethodError:找不到特定的方法。Jar包冲突,导致选择了错误的依赖版本,该依赖版本中的类对不存在该方法,或该方法已经被升级.
抛出java.lang.NoClassDefFoundError,java.lang.LinkageError等,原因同上.
没有异常但预期结果不同:加载了错误的版本,不同的版本底层实现不同,导致预期结果不一致.
Jar包冲突的本质: Java应用程序因某种因素,加载不到正确的类而导致其行为跟预期不一致 .
具体分两种情况:
情况一:项目依赖了同一Jar包的多个版本,并且选错了版本; 。
情况二:同样的类在不同的Jar包中出现,导致JVM加载了错误的类; 。
情况一 ,同一个依赖引入了多个Jar包版本,不同的Jar包版本有不同的类和方法。由于Maven依赖树的仲裁机制导致Maven加载了错误的Jar包,从而导致Jar包冲突; 。
情况二 ,同一类在不同的Jar包中出现。这种情况是由于JVM的同一个类加载器对于同一个类只会加载一次,现在加载一个类之后,同全限定名的类便不会进行加载,从而出现Jar包冲突的问题.
针对第二种情况,如果不是类冲突抛出了异常,你可能根本意识不到,所以就显得更为棘手。这种情况就可以采用前文所述的通过分析不同类加载器的优先级及加载路径、文件系统的文件加载顺序等进行调整来解决.
几种场景下解决Jar冲突的方法:
Maven默认处理:路径最近者优先和第一声明优先; 。
排除法:使用 Maven Helper,可以将冲突的Jar包在pom.xml中通过 exclude 来进行排除; 。
版本锁定法:如果项目中依赖同一Jar包的很多版本,一个个排除非常麻烦,此时可用 版本锁定法 ,即直接明确引入指定版本的依赖。此种方式的优先级最高.
通过设置classpath指定jar包加载的先后顺序 。
具体步骤 : 。
1.使用mavenHelper 选择 Confilicts; 。
2.如果列表存在冲突的依赖,则点击查看冲突的详情 。
3.对冲突的依赖可进行右键;使用 exclude 进行排除即可解决冲突 。
java -jar -classpath C:\dependency\framework.jar:C:\location\otherFramework.jar test.jar
第二种方式(-cp 等于 -classpath):
java -jar -cp C:\dependency\framework.jar:C:\location\otherFramework.jar test.jar
第三种方式:
-Djava.
class
.path=a.jar
第四种方式:
-Xbootclasspath/a:
当在Maven项目中引入A的依赖,A的依赖通常又会引入B的jar包,B可能还会引入C的jar包。这样,当你在pom.xml文件中添加了A的依赖,Maven会自动的帮你把所有相关的依赖都添加进来.
如下图所示,项目 A 依赖于项目 B,B 又依赖于项目 C,此时 B 是 A 的直接依赖,C 是 A 的间接依赖.
Maven 的依赖传递机制是指:不管 Maven 项目存在多少间接依赖,POM 中都只需要定义其直接依赖,不必定义任何间接依赖,Maven 会动读取当前项目各个直接依赖的 POM,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中。Maven 的依赖传递机制能够帮助用户一定程度上简化 POM 的配置.
基于 A、B、C 三者的依赖关系,根据 Maven 的依赖传递机制,我们只需要在项目 A 的 POM 中定义其直接依赖 B,在项目 B 的 POM 中定义其直接依赖 C,Maven 会解析 A 的直接依赖 B的 POM ,将间接依赖 C 以传递性依赖的形式引入到项目 A 中.
即当一个依赖需要另外一个依赖支撑时,Maven会帮我们把相应的依赖依次添加到项目当中。这样的好处是,使用起来就非常方便,不用自己挨个去找依赖Jar包了。坏处是会引起Jar包冲突, 。
但当一个间接依赖存在多条引入路径时,为了避免出现依赖重复的问题,Maven 通过依赖调节来确定间接依赖的引入路径.
依赖调节遵循以下两条原则:
引入路径短者优先 。
先声明者优先 。
引入路径短者优先,顾名思义,当一个间接依赖存在多条引入路径时,引入路径短的会被解析使用.
例如,A 存在这样的依赖关系: A->B->C->D(1.0) A->X->D(2.0) 。
D 是 A 的间接依赖,但两条引入路径上有两个不同的版本,很显然不能同时引入,否则造成重复依赖的问题。根据 Maven 依赖调节的第一个原则:引入路径短者优先,D(1.0)的路径长度为 3,D(2.0)的路径长度为 2,因此间接依赖 D(2.0)将从 A->X->D(2.0) 路径引入到 A 中.
先声明者优先,顾名思义,在引入路径长度相同的前提下,POM 文件中依赖声明的顺序决定了间接依赖会不会被解析使用,顺序靠前的优先使用.
例如,A 存在以下依赖关系: A->B->D(1.0) A->X->D(2.0) 。
D 是 A 的间接依赖,其两条引入路径的长度都是 2,此时 Maven 依赖调节的第一原则已经无法解决,需要使用第二原则:先声明者优先.
最后,梳理一下Tomcat启动时,对Jar包和类的加载顺序,其中包含上面提到的不同种类的类加载器默认加载的目录:
上述目录中,同一文件夹下的Jar包,按照顺序从上到下一次加载。如果一个class文件已经被加载到JVM中,后面相同的class文件就不会被加载了 。
最后此篇关于Maven依赖冲突解决总结的文章就讲到这里了,如果你想了解更多关于Maven依赖冲突解决总结的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我的工作是将每条记录写入 Hadoop 映射中的 DynamoDB。 我无法使用具有 httpclient-4.2.5.jar 和 httpcore-4.2.5.jar 的 Hadoop 2.6 运行
我在 JavaScript 中嵌套了循环开关,例如: for (var i = 0; i < checkBoxIds.length; i++) { if ($('#' + checkB
我有一个文件夹被重命名的分支。现在我正在尝试合并从主干到这个分支的更改,但是在主干中修改的文件仍然在原始文件夹名称下,因此 svn 引发了树冲突。我该如何解决这个问题? 该文件夹已使用 svn ren
我在使用 jquery 暴露插件和 Masked 输入插件时遇到了问题。问题是它们都占用 $.mask 函数,从而导致冲突。但我非常需要这两个插件一起工作。我会将其中一个中的 $.mask 重命名为.
我正在尝试为我所有的 INPUT 元素做一个简单的 :focus 效果,就像这样: INPUT:focus { border-color: orange; } 这很好用,直到我将这段 CSS 添加到样
我是 javascript 的新手。 在 wordpress 上工作,我在自定义 js 中为我的主题输入了以下函数: document.getElementsByName("empty_cart")[
为什么有些 javascript 会与其他的发生冲突?我的意思是我一直在为图片库使用 javascript 代码,然后尝试在 jquery 中获取文本水印。为什么在使用 jquery 之后,画廊完全消
是否可以根据已知的输入值创建 MD5 碰撞? 所以例如我有输入字符串 abc与 MD5 900150983cd24fb0d6963f7d28e17f72 . 现在我想将字节添加到字符串 def获得相同
我在我的项目中使用原型(prototype): NodeParser.prototype.getChildren = function(parentContainer) { return fl
根据我对 merge 冲突的理解,当两个人更改了同一文件和/或修改了该文件中的同一行时,就会发生 merge 冲突。所以当我做一个 git pull origin master 我期望 merge 冲
iPad 上 Mobile Safari 中的 HTML5 模板。带 iScroll 的 Div 工作正常。 if/else 语句中还包含一个 jQuery 函数。该函数测试用户是否在 iScroll
我一直在尝试使 2 个脚本(1 个 mootol 和 1 个 jquery)在同一页面上工作,但没有成功。我一直在研究许多论坛等,但我仍然无法使这两个脚本同时工作。 这就是它在我的标题中的样子: /w
我想克隆带标题的问号。一切正常,但是当我将鼠标悬停在新问号上时,第一个问号上会出现工具提示。有什么想法吗? 我正在使用 jQuery 和醉酒的工具提示。 Demo here click here
好吧,我已经在一个 friend 的网站上工作了一段时间了。我的编码技能......值得怀疑,而且我遇到了很多问题。 目前我网站上的 jQuery 停止工作了,我找不到原因,并且我已尽一切努力让它工作
我想使用一个文件来保存所有#define 和常量:示例 #ifndef CONSTANTS_H_ #define CONSTANTS_H_ #include //OVERALL DEFS
我在我的表单中的所有 HTML 下都有一些验证码,这似乎阻止了我的复选框验证码的工作,一旦我在我的 HTML 下的代码周围添加/* */(使其不活动),我就得出了这个结论) 复选框验证代码开始正常工作
我是新手。我的页面上有两个 javascript/jquery。如果我使用第一个脚本,第二个脚本将不起作用。如果我删除第一个脚本,第二个脚本就可以正常工作。我不知道如何解决这个问题。我知道有一个“无冲
我是 Bison 新手,在处理 Shift/Reduce 冲突时遇到了麻烦... 我正在为C语言编写语法规则:ID是标识变量的标记,我编写此规则是为了确保即使将标识符写在括号中,也可以考虑它。 id
我目前正在使用 LibGdx 开发我的第一个 Android 游戏项目。这是一款 2D 迷宫游戏,您可以使用触摸输入从其中一个入口到其中一个导出“画出”一条线。世界本身是一个 TiledMap,目前仅
我正在尝试通过 javascript 完成表单验证,并在 #form# 标记中放置一个要执行的 .py 文件操作。但问题是,当我提交数据后,它不会重定向到 .py 操作。所以我摆脱了 preventd
我是一名优秀的程序员,十分优秀!