如何解决包ios 解决手势冲突问题题

maven 隐式依赖引起的包冲突解决办法
转载 & & 投稿:lqh
这篇文章主要介绍了maven 隐式依赖引起的包冲突解决办法的相关资料,需要的朋友可以参考下
1.使用maven管理项目时可能会遇到包冲突的情况比如:log4j-over-slf4j.jar 和 slf4j-log4j12.jar这两个包同时一起运行时就会有问题。
2.这种冲突可能是显式依赖导致,也可能是隐式依赖导致。
显式依赖,直接可以从pom.xml文件的&dependency&中看到两个冲突包的引用。
隐式依赖,在pom.xml的&dependency&无法看到冲突的包,而是由&dependency&引入的包间接引入的。
先确认哪些依赖间接引入了包。使用mvn dependency:tree查看整个项目的依赖树,这里能看到所有的依赖,包括间接依赖。
结果类似如下:
[INFO] +- junit:junit:jar:4.12:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.apache.storm:storm-core:jar:1.0.2:provided
[INFO] | +- com.esotericsoftware:kryo:jar:3.0.3:compile
[INFO] | | \- com.esotericsoftware:minlog:jar:1.3.0:compile
[INFO] | +- org.clojure:clojure:jar:1.7.0:provided
[INFO] | +- com.lmax:disruptor:jar:3.3.2:provided
[INFO] | +- org.apache.logging.log4j:log4j-api:jar:2.1:provided
[INFO] | +- org.apache.logging.log4j:log4j-core:jar:2.1:provided
[INFO] | +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.1:provided
[INFO] | +- org.slf4j:log4j-over-slf4j:jar:1.6.6:provided
[INFO] | +- javax.servlet:servlet-api:jar:2.5:provided
[INFO] | \- org.slf4j:slf4j-api:jar:1.7.7:compile
[INFO] +- com.aaa.khala:aaa-khala-insight-sdk-transfer-api:jar:1.0.0-SNAPSHOT:compile
[INFO] | \- com.aaa.khala:aaa-khala-common:jar:1.0.0-SNAPSHOT:compile
+- javax.mail:javax.mail-api:jar:1.5.5:compile
+- cglib:cglib:jar:2.2.2:compile
+- org.aspectj:aspectjrt:jar:1.7.4:compile
+- org.aspectj:aspectjweaver:jar:1.7.4:runtime
+- org.javassist:javassist:jar:3.20.0-GA:compile
+- log4j:log4j:jar:1.2.17:compile
+- org.slf4j:slf4j-log4j12:jar:1.7.7:compile
+- dom4j:dom4j:jar:1.6.1:compile
+- jaxen:jaxen:jar:1.1.6:compile
+- commons-collections:commons-collections:jar:3.2.1:compile
+- commons-codec:commons-codec:jar:1.9:compile
+- commons-beanutils:commons-beanutils:jar:1.9.2:compile
+- org.apache.commons:commons-compress:jar:1.6:compile
| \- org.tukaani:xz:jar:1.4:compile
查到冲突包对应的依赖,在pom.xml的&dependency&中配置排除,就不会引入该包了,例如:
&dependency&
&groupId&com.aaa.khala&/groupId&
&artifactId&aaa-khala-insight-sdk-transfer-api&/artifactId&
&version&1.0.0-SNAPSHOT&/version&
&exclusions&
&exclusion&
&groupId&org.slf4j&/groupId&
&artifactId&slf4j-log4j12&/artifactId&
&/exclusion&
&/exclusions&
&/dependency&
&感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具一次完整的jar包冲突解决过程&从iteye导入&
作为Java程序员,会经常碰到jar包冲突,特别是涉及到的外部依赖越多,冲突概率就会越大。由于我们的应用代码都是使用maven来管理的,所以依赖的解决相对比较容易。不过最近碰到的一个问题,确实经历了好多步才最终定位。
现象:应用启动过程中,spring容器启动失败,错误日志很明确,找不到CollectionUtils.isEmpty()方法,jar冲突的典型症状之一。
首先,确认了这个类是apache的commons-collections中的工具类(在eclipse中ctrl+shift+T或者command+shitf+T寻找CollectionUtils是来自哪个jar中,同时也可以看看是不是含有这个方法),那么执行maven命令分析依赖树mvn dependency:tree -e -Dincludes=*:commons-collections*,看看应用中如何依赖commons-collections,依赖路径以及依赖版本。结果稍微出乎意料,有两个commons-collections依赖,只是groupId不同(这个时候maven是无能为力的,maven会认为这两个依赖是不同的,不会认为是一样的,因为maven对依赖的标识就是坐标,与jar中的内容无关),一个是apache-collections,另外一个是commons-collections,查看第二个中的CollectionUtils是有isEmpty方法的,第一个是没有的,而且第一个jar和第二个jar的包结构是完全相同的,apache-collections是外部系统的类库引入的,感觉好奇葩,于是果断排除之。重新查看依赖树,OK,打包重启,依然相同的错误。
接下来,打开war包,看下WEB-INF/lib下的commons-collections确实是3.2.1,没有问题。说明war包没有问题,最起码war内不会冲突,war包没问题。那就是jboss有问题,由于之前碰到过类似的问题,直接去${jboss_home}/server/default/lib下查看,升级其中的commons-collections到3.2.1即可(应用的jar和容器中的冲突的话,以容器为主,因为容器被优先加载),无需打包,重启jboss。自信满满地以为问题解决了,结果错误还是没变。
继续,查看jboss其他的目录,看不到commons-collections的影子。貌似到此,无路可走了。所以想想,服务器上肯定还有commons-collections-3.1存在,或许是在隐藏目录中(为毛当时没想起来用find名称搜索commons-collections)。没办法,只能通过打日志来看看CollectionUtils是从哪儿加载的了,使用了几行代码:
URL url = getClass().getClassLoader().getResource("org/apache/commons/collections/CollectionUtils.class");
LOG.error("CollectionUtils is loading from {}", url.getPath());
重新打包部署之后,查看日志信息,显示CollectionUtils是用WEB-INF/lib/commons-collections-3.2.1.jar中加载的,真的好意外,一直都在说,jboss中的jar优先加载啊,然后才会加载war的?那为神马会显示是用war中加载的呢?而且war中的是jar包版本是OK的,至此,基本无路可走了。除非?除非那个获取加载路径的代码是有问题的,因为和我的认知确实是冲突的。于是就getResource()方法去问了web容器方面的“神”,给出的解释是这个方法返回的路径不一定是真实的加载路径,和具体的容器实现有关。
最后,貌似打开了思路,但是什么办法可以知道类的真实记载路径呢?jvm启动参数跟踪,-XX:+TraceClassLoading加在jboss其中参数中,重启jboss,查看应用启动之后的jboss日志。好吧,日志文件很大,搜索下CollectionsUtils,确实是从一个隐藏目录加载的commons-collections,问题定位到了,解决办法不用说了。
如果前边真的用find(find / -name "common-collections" -print)命令搜索解决了问题,那么也不会有后边对认知的颠覆,那样还会一直认为那个api是救命稻草呢,不知道要持续到什么时候呢。另外,用find命令也只能去试探性地搜索commons-collections这个文件,但是不能排除有的类库会把commons-collections的代码内嵌在自己的jar中,这种事儿见到不少。所以走了最长的路,收获一定是最多的:)。
补充一下:团队之前采取的方案一直是不采用这个方法来判断,其实也就是为了避开这个坑,这种做法多少有点不太负责任,毕竟依赖在classpath上,IDE会直接提示补充完善代码,只有踩了坑的人才知道不能用,而且还不知道根源,这样下去,我只能呵呵了。
Copyright (C) , All Rights Reserved.
版权所有 闽ICP备号
processed in 0.033 (s). 13 q(s)&>&Maven类包冲突终极解决小技若干
Maven类包冲突终极解决小技若干
上传大小:502KB
Maven类包冲突终极解决小技若干
综合评分:0
下载个数:
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有0条
综合评分:
积分/C币:3
综合评分:
积分/C币:3
综合评分:
积分/C币:3
综合评分:
积分/C币:10
supersilly
综合评分:
积分/C币:3
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
Maven类包冲突终极解决小技若干
会员到期时间:
剩余下载个数:
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
无法举报自己的资源
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可返还被扣除的积分
被举报人:
举报的资源分:
请选择类型
资源无法下载 ( 404页面、下载失败、资源本身问题)
资源无法使用 (文件损坏、内容缺失、题文不符)
侵犯版权资源 (侵犯公司或个人版权)
虚假资源 (恶意欺诈、刷分资源)
含色情、危害国家安全内容
含广告、木马病毒资源
*详细原因:
Maven类包冲突终极解决小技若干重新看待Jar包冲突问题及解决方案 - 简书
重新看待Jar包冲突问题及解决方案
Jar包冲突是老生常谈的问题,几乎每一个Java程序猿都不可避免地遇到过,并且也都能想到通常的原因一般是同一个Jar包由于maven传递依赖等原因被引进了多个不同的版本而导致,可采用依赖排除、依赖管理等常规方式来尝试解决该问题,但这些方式真正能彻底解决该冲突问题吗?答案是否定的。笔者之所以将文章题目起为“重新看待”,是因为之前对于Jar包冲突问题的理解仅仅停留在前面所说的那些,直到在工作中遇到的一系列Jar包冲突问题后,才发现并不是那么简单,对该问题有了重新的认识,接下来本文将围绕Jar包冲突的问题本质和相关的解决方案这两个点进行阐述。
Jar包冲突问题
一、冲突的本质
Jar包冲突的本质是什么?Google了半天也没找到一个让人满意的完整定义。其实,我们可以从Jar包冲突产生的结果来总结,在这里给出如下定义(此处如有不妥,欢迎拍砖-):
Java应用程序因某种因素,加载不到正确的类而导致其行为跟预期不一致。
具体来说可分为两种情况:1)应用程序依赖的同一个Jar包出现了多个不同版本,并选择了错误的版本而导致JVM加载不到需要的类或加载了错误版本的类,为了叙述的方便,笔者称之为第一类Jar包冲突问题;2)同样的类(类的全限定名完全一样)出现在多个不同的依赖Jar包中,即该类有多个版本,并由于Jar包加载的先后顺序导致JVM加载了错误版本的类,称之为第二类Jar包问题。这两种情况所导致的结果其实是一样的,都会使应用程序加载不到正确的类,那其行为自然会跟预期不一致了,以下对这两种类型进行详细分析。
1.1 同一个Jar包出现了多个不同版本
随着Jar包迭代升级,我们所依赖的开源的或公司内部的Jar包工具都会存在若干不同的版本,而版本升级自然就避免不了类的方法签名变更,甚至于类名的更替,而我们当前的应用程序往往依赖特定版本的某个类 M ,由于maven的传递依赖而导致同一个Jar包出现了多个版本,当maven的仲裁机制选择了错误的版本时,而恰好类 M在该版本中被去掉了,或者方法签名改了,导致应用程序因找不到所需的类 M或找不到类 M中的特定方法,就会出现第一类Jar冲突问题。可总结出该类冲突问题发生的以下三个必要条件:
由于maven的传递依赖导致依赖树中出现了同一个Jar包的多个版本
该Jar包的多个版本之间存在接口差异,如类名更替,方法签名更替等,且应用程序依赖了其中有变更的类或方法
maven的仲裁机制选择了错误的版本
1.2 同一个类出现在多个不同Jar包中
同样的类出现在了应用程序所依赖的两个及以上的不同Jar包中,这会导致什么问题呢?我们知道,同一个类加载器对于同一个类只会加载一次(多个不同类加载器就另说了,这也是解决Jar包冲突的一个思路,后面会谈到),那么当一个类出现在了多个Jar包中,假设有 A 、 B 、 C 等,由于Jar包依赖的路径长短、声明的先后顺序或文件系统的文件加载顺序等原因,类加载器首先从Jar包 A 中加载了该类后,就不会加载其余Jar包中的这个类了,那么问题来了:如果应用程序此时需要的是Jar包 B 中的类版本,并且该类在Jar包 A 和 B 中有差异(方法不同、成员不同等等),而JVM却加载了Jar包 A 的中的类版本,与期望不一致,自然就会出现各种诡异的问题。
从上面的描述中,可以发现出现不同Jar包的冲突问题有以下三个必要条件:
同一个类 M 出现在了多个依赖的Jar包中,为了叙述方便,假设还是两个: A 和 B
Jar包 A 和 B 中的该类 M 有差异,无论是方法签名不同也好,成员变量不同也好,只要可以造成实际加载的类的行为和期望不一致都行。如果说Jar包 A 和 B 中的该类完全一样,那么类加载器无论先加载哪个Jar包,得到的都是同样版本的类 M ,不会有任何影响,也就不会出现Jar包冲突带来的诡异问题。
加载的类 M 不是所期望的版本,即加载了错误的Jar包
二、冲突的产生原因
2.1 maven仲裁机制
当前maven大行其道,说到第一类Jar包冲突问题的产生原因,就不得不提了。传递性依赖是Maven2.0引入的新特性,让我们只需关注直接依赖的Jar包,对于间接依赖的Jar包,Maven会通过解析从远程仓库获取的依赖包的pom文件来隐式地将其引入,这为我们开发带来了极大的便利,但与此同时,也带来了常见的问题——版本冲突,即同一个Jar包出现了多个不同的版本,针对该问题Maven也有一套仲裁机制来决定最终选用哪个版本,但Maven的选择往往不一定是我们所期望的,这也是产生Jar包冲突最常见的原因之一。先来看下Maven的仲裁机制:
优先按照依赖管理&dependencyManagement&元素中指定的版本声明进行仲裁,此时下面的两个原则都无效了
若无版本声明,则按照“短路径优先”的原则(Maven2.0)进行仲裁,即选择依赖树中路径最短的版本
若路径长度一致,则按照“第一声明优先”的原则进行仲裁,即选择POM中最先声明的版本
从maven的仲裁机制中可以发现,除了第一条仲裁规则(这也是解决Jar包冲突的常用手段之一)外,后面的两条原则,对于同一个Jar包不同版本的选择,maven的选择有点“一厢情愿”了,也许这是maven研发团队在总结了大量的项目依赖管理经验后得出的两条结论,又或者是发现根本找不到一种统一的方式来满足所有场景之后的无奈之举,可能这对于多数场景是适用的,但是它不一定适合我——当前的应用,因为每个应用都有其特殊性,该依赖哪个版本,maven没办法帮你完全搞定,如果你没有规规矩矩地使用&dependencyManagement&来进行依赖管理,就注定了逃脱不了第一类Jar包冲突问题。
2.1 Jar包的加载顺序
对于第二类Jar包冲突问题,即多个不同的Jar包有类冲突,这相对于第一类问题就显得更为棘手。为什么这么说呢?在这种情况下,两个不同的Jar包,假设为 A、 B,它们的名称互不相同,甚至可能完全不沾边,如果不是出现冲突问题,你可能都不会发现它们有共有的类!对于A、B这两个Jar包,maven就显得无能为力了,因为maven只会为你针对同一个Jar包的不同版本进行仲裁,而这俩是属于不同的Jar包,超出了maven的依赖管理范畴。此时,当A、B都出现在应用程序的类路径下时,就会存在潜在的冲突风险,即A、B的加载先后顺序就决定着JVM最终选择的类版本,如果选错了,就会出现诡异的第二类冲突问题。
那么Jar包的加载顺序都由哪些因素决定的呢?具体如下:
Jar包所处的加载路径,或者换个说法就是加载该Jar包的类加载器在JVM类加载器树结构中所处层级。由于JVM类加载的双亲委派机制,层级越高的类加载器越先加载其加载路径下的类,顾名思义,引导类加载器(bootstrap ClassLoader,也叫启动类加载器)是最先加载其路径下Jar包的,其次是扩展类加载器(extension ClassLoader),再次是系统类加载器(system ClassLoader,也就是应用加载器appClassLoader),Jar包所处加载路径的不同,就决定了它的加载顺序的不同。比如我们在eclipse中配置web应用的resin环境时,对于依赖的Jar包是添加到Bootstrap Entries中还是User Entries中呢,则需要仔细斟酌下咯。
文件系统的文件加载顺序。这个因素很容易被忽略,而往往又是因环境不一致而导致各种诡异冲突问题的罪魁祸首。因tomcat、resin等容器的ClassLoader获取加载路径下的文件列表时是不排序的,这就依赖于底层文件系统返回的顺序,那么当不同环境之间的文件系统不一致时,就会出现有的环境没问题,有的环境出现冲突。例如,对于Linux操作系统,返回顺序则是由iNode的顺序来决定的,如果说测试环境的Linux系统与线上环境不一致时,就极有可能出现典型案例:测试环境怎么测都没问题,但一上线就出现冲突问题,规避这种问题的最佳办法就是尽量保证测试环境与线上一致。
三、冲突的表象
Jar包冲突可能会导致哪些问题?通常发生在编译或运行时,主要分为两类问题:一类是比较直观的也是最为常见的错误是抛出各种运行时异常,还有一类就是比较隐晦的问题,它不会报错,其表现形式是应用程序的行为跟预期不一致,分条罗列如下:
java.lang.ClassNotFoundException,即java类找不到。这类典型异常通常是由于,没有在依赖管理中声明版本,maven的仲裁的时候选取了错误的版本,而这个版本缺少我们需要的某个class而导致该错误。例如httpclient-4.4.jar升级到httpclient-4.36.jar时,类org.apache.http.conn.ssl.NoopHostnameVerifier被去掉了,如果此时我们本来需要的是4.4版本,且用到了NoopHostnameVerifier这个类,而maven仲裁时选择了4.6,则会导致ClassNotFoundException异常。
java.lang.NoSuchMethodError,即找不到特定方法,第一类冲突和第二类冲突都可能导致该问题——加载的类不正确。若是第一类冲突,则是由于错误版本的Jar包与所需要版本的Jar包中的类接口不一致导致,例如antlr-2.7.2.jar升级到antlr-2.7.6.Jar时,接口antlr.collections.AST.getLine()发生变动,当maven仲裁选择了错误版本而加载了错误版本的类AST,则会导致该异常;若是第二类冲突,则是由于不同Jar包含有的同名类接口不一致导致,典型的案例:Apache的commons-lang包,2.x升级到3.x时,包名直接从commons-lang改为commons-lang3,部分接口也有所改动,由于包名不同和传递性依赖,经常会出现两种Jar包同时在classpath下,org.apache.commons.lang.StringUtils.isBlank就是其中有差异的接口之一,由于Jar包的加载顺序,导致加载了错误版本的StringUtils类,就可能出现NoSuchMethodError异常。
java.lang.NoClassDefFoundError,java.lang.LinkageError等,原因和上述雷同,就不作具体案例分析了。
没有报错异常,但应用的行为跟预期不一致。这类问题同样也是由于运行时加载了错误版本的类导致,但跟前面不同的是,冲突的类接口都是一致的,但具体实现逻辑有差异,当我们加载的类版本不是我们需要的实现逻辑,就会出现行为跟预期不一致问题。这类问题通常发生在我们自己内部实现的多个Jar包中,由于包路径和类名命名不规范等问题,导致两个不同的Jar包出现了接口一致但实现逻辑又各不相同的同名类,从而引发此问题。
一、问题排查和解决
如果有异常堆栈信息,根据错误信息即可定位导致冲突的类名,然后在eclipse中CTRL+SHIFT+T或者在idea中CTRL+N就可发现该类存在于多个依赖Jar包中
若步骤1无法定位冲突的类来自哪个Jar包,可在应用程序启动时加上JVM参数-verbose:class或者-XX:+TraceClassLoading,日志里会打印出每个类的加载信息,如来自哪个Jar包
定位了冲突类的Jar包之后,通过mvn dependency:tree -Dverbose -Dincludes=&groupId&:&artifactId&查看是哪些地方引入的Jar包的这个版本
确定Jar包来源之后,如果是第一类Jar包冲突,则可用&excludes&排除不需要的Jar包版本或者在依赖管理&dependencyManagement&中申明版本;若是第二类Jar包冲突,如果可排除,则用&excludes&排掉不需要的那个Jar包,若不能排,则需考虑Jar包的升级或换个别的Jar包。当然,除了这些方法,还可以从类加载器的角度来解决该问题,可参考博文——,其思路值得借鉴。
二、有效避免
从上一节的解决方案可以发现,当出现第二类Jar包冲突,且冲突的Jar包又无法排除时,问题变得相当棘手,这时候要处理该冲突问题就需要较大成本了,所以,最好的方式是在冲突发生之前能有效地规避之!就好比数据库死锁问题,死锁避免和死锁预防就显得相当重要,若是等到真正发生死锁了,常规的做法也只能是回滚并重启部分事务,这就捉襟见肘了。那么怎样才能有效地规避Jar包冲突呢?
2.1 良好的习惯:依赖管理
对于第一类Jar包冲突问题,通常的做法是用&excludes&排除不需要的版本,但这种做法带来的问题是每次引入带有传递性依赖的Jar包时,都需要一一进行排除,非常麻烦。maven为此提供了集中管理依赖信息的机制,即依赖管理元素&dependencyManagement&,对依赖Jar包进行统一版本管理,一劳永逸。通常的做法是,在parent模块的pom文件中尽可能地声明所有相关依赖Jar包的版本,并在子pom中简单引用该构件即可。
来看个示例,当开发时确定使用的httpclient版本为4.5.1时,可在父pom中配置如下:
&properties&
&httpclient.version&4.5.1&/httpclient.version&
&/properties&
&dependencyManagement&
&dependencies&
&dependency&
&groupId&org.apache.httpcomponents&/groupId&
&artifactId&httpclient&/artifactId&
&version&${httpclient.version}&/version&
&/dependency&
&/dependencies&
&/dependencyManagement&
然后各个需要依赖该Jar包的子pom中配置如下依赖:
&dependencies&
&dependency&
&groupId&org.apache.httpcomponents&/groupId&
&artifactId&httpclient&/artifactId&
&/dependency&
&/dependencies&
2.2 冲突检测插件
对于第二类Jar包冲突问题,前面也提到过,其核心在于同名类出现在了多个不同的Jar包中,如果人工来排查该问题,则需要逐个点开每个Jar包,然后相互对比看有没同名的类,那得多么浪费精力啊?!好在这种费时费力的体力活能交给程序去干。maven-enforcer-plugin,这个强大的maven插件,配合extra-enforcer-rules工具,能自动扫描Jar包将冲突检测并打印出来,汗颜的是,笔者工作之前居然都没听过有这样一个插件的存在,也许是没遇到像工作中这样的冲突问题,算是涨姿势了。其原理其实也比较简单,通过扫描Jar包中的class,记录每个class对应的Jar包列表,如果有多个即是冲突了,故不必深究,我们只需要关注如何用它即可。
在最终需要打包运行的应用模块pom中,引入maven-enforcer-plugin的依赖,在build阶段即可发现问题,并解决它。比如对于具有parent pom的多模块项目,需要将插件依赖声明在应用模块的pom中。这里有童鞋可能会疑问,为什么不把插件依赖声明在parent pom中呢?那样依赖它的应用子模块岂不是都能复用了?这里之所以强调“打包运行的应用模块pom”,是因为冲突检测针对的是最终集成的应用,关注的是应用运行时是否会出现冲突问题,而每个不同的应用模块,各自依赖的Jar包集合是不同的,由此而产生的&ignoreClasses&列表也是有差异的,因此只能针对应用模块pom分别引入该插件。
先看示例用法如下:
&groupId&org.apache.maven.plugins&/groupId&
&artifactId&maven-enforcer-plugin&/artifactId&
&version&1.4.1&/version&
&executions&
&execution&
&id&enforce&/id&
&configuration&
&dependencyConvergence/&
&/configuration&
&goal&enforce&/goal&
&/execution&
&execution&
&id&enforce-ban-duplicate-classes&/id&
&goal&enforce&/goal&
&configuration&
&banDuplicateClasses&
&ignoreClasses&
&ignoreClass&javax.*&/ignoreClass&
&ignoreClass&org.junit.*&/ignoreClass&
&ignoreClass&net.sf.cglib.*&/ignoreClass&
&ignoreClass&org.apache.commons.logging.*&/ignoreClass&
&ignoreClass&org.springframework.remoting.rmi.RmiInvocationHandler&/ignoreClass&
&/ignoreClasses&
&findAllDuplicates&true&/findAllDuplicates&
&/banDuplicateClasses&
&fail&true&/fail&
&/configuration&
&/execution&
&/executions&
&dependencies&
&dependency&
&groupId&org.codehaus.mojo&/groupId&
&artifactId&extra-enforcer-rules&/artifactId&
&version&1.0-beta-6&/version&
&/dependency&
&/dependencies&
maven-enforcer-plugin是通过很多预定义的标准规则()和用户自定义规则,来约束maven的环境因素,如maven版本、JDK版本等等,它有很多好用的特性,具体可参见。而Extra Enforcer Rules则是MojoHaus项目下的针对maven-enforcer-plugin而开发的提供额外规则的插件,这其中就包含前面所提的重复类检测功能,具体用法可参见,这里就不详细叙述了。
第一类Jar包冲突
这类Jar包冲突是最常见的也是相对比较好解决的,已经在这节中列举了部分案例,这里就不重复列举了。
第二类Jar包冲突
Spring2.5.6与Spring3.x
Spring2.5.6与Spring3.x,从单模块拆分为多模块,Jar包名称(artifactId)也从spring变为spring-submoduleName,如
spring-context、spring-aop等等,并且也有少部分接口改动(Jar包升级的过程中,这也是在所难免的)。由于是不同的Jar包,经maven的传递依赖机制,就会经常性的存在这俩版本的Spring都在classpath中,从而引发潜在的冲突问题。
行万里路,读万卷书
Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线)。分布式系统的协调导致了样板模式, 使用Spring Cloud开发人员可以快速地支持实现这些模式的服务和应用程序。他们将在任何分布式...
Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgbook/spring-boot-reference-guide-zh/details带目录浏览地址:http://www.maoyupeng.com/sprin...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金相信有很多朋友...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金 相信有很多...
jar依赖冲突解决实践 随着功能的增多,各种中间件的引入。应用以来的各种jar的规模极具膨胀,出现jar冲突和Class冲突的问题层出不穷,让人不胜其扰。本文针对冲突,提供一个排查和定位问题的最佳实践。实践中尽量不借助第三方工具,而使用maven或者Linux的自带命令行。...
身边的小伙伴都在涂填《秘密花园》,自己也兴冲冲买来涂写勾勒,却只画了几张就沉入箱底;小时候看到别人集邮,收获颇丰,自己也想培养这样的爱好、习惯,但收集一段时间后,逐渐就放在一边;出去旅游看到很多人背着单反拍照,冲动买下,只用了一次就锁到柜子;看到朋友在朋友圈“晒”做各种美食...
坐班、打工、兼职、创业,亦或是每天疲于应付单位里那些无聊的工作或人际关系。 不管我们之间差别有多大,做的事有多么不同,身后仿佛都有一个让我们无法停下来的东西,推搡着、催促着我们加快脚步、不停忙碌。 忙碌得久了,当忙碌成为一种习惯,偶然某一天得以闲暇可以仰望星空、俯瞰大地的时...
锐眼视点: DeepMind 向 AI 研究人员开放 Lab 平台; Microsoft 全新上线聊天机器人 Zo; DataRobot 运用深度学习从高级模型中获取洞察。 [业界新闻]DeepMind 向 AI 研究人员开放 flagship 平台 世界各地的 AI 研究...
第一部分:工具包的基础概念 在《学习的本质》一书里,有这么一段话: 在这两极(笔者注:指单薄的思维结构和坚实的思维结构两极)之间存在一个区间,学习者在那里精心组织自己的观点,并在他感觉到自己的先有概念有局限或者已失效时炼制一种新观点。他有多种策略可以使用。他可以完全独立自主...

我要回帖

更多关于 ios 解决手势冲突问题 的文章

 

随机推荐