如何解决jar包冲突怎么解决问题

android 同一个项目存在相同jar包冲突问题如何解决?
问题是这样的:本人在开发一个sdk其中集成了一个jar 当客户集成此sdk时,如果他也依赖了那个jar包 便会编译报错 求助如何解决?有人建议删除一个jar包,这个不可行,因为如果客户没有集成那个jar 便需要使用sdk中集成的jar
删掉一个- -如果是第三方库存在的jar包和外面的jar包冲突的话就删掉外面的试试看 - -
已有帐号?
无法登录?
社交帐号登录<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&一、问题定义
最近在用sbt打assembly包时出现问题,在package的时候,发生jar包冲突/文件冲突问题,两个相同的class来自不同的jar包在classpath内引起冲突。
具体是:我有一个self4j的jar, 还有一个hadoop-common-hdfs的jar包,其中hadoop-common-hdfs.jar内包含了self4j这个jar包,导致冲突。
此类异常一般是由于打包不规范和打包疏忽引起的。
(个人认为正确的打包策略是:只打包自己核心功能,不将依赖打包在一起,但是有时为了方便不得不打在一起,所以要注意可能会出现上述问题)
异常log如下:
[trace] Stack trace suppressed: run last *:assembly for the full output.
[error] (*:assembly) deduplicate: different file contents found in the following:
[error] C:\Users\shengli.victor\.ivy2\cache\org.slf4j\slf4j-api\jars\slf4j-api-1.7.7.jar:org/slf4j/IMarkerFactory.class
[error] C:\Users\shengli.victor\.ivy2\cache\com.xxx.xx.hdfsfile\hdfscommon\jars\hdfscommon-1.1.jar:org/slf4j/IMarkerFactory.class
[error] Total time: 4 s, completed
异常很明显,来自2个不同的jar包self4j, &hdfscommon-1.1.jar里,在org/slf4j/IMarkerFactory.class这个类冲突了。
hdfscommon-1.1/jar
slf4j-api-1.7.2.jar
二、解决方案
解决jar包冲突有两种方案:
1、删除其中的某个jar,或者说,在打包的时候,不将2个相同的class打在同一个jar包内的classpath内,即exclude jar。
2、合并冲突
1.&Excluding JARs and files
%&&provided&
将相同的jar中排除一个,因为重复,可以使用&provided&关键字。
例如spark是一个容器类,编写spark应用程序我们需要spark core jar. 但是真正打包提交到集群上执行,则不需要将它打入jar包内。
这是我们使用 % &provided& 关键字来exclude它。
libraryDependencies ++= Seq(
&org.apache.spark& %% &spark-core& % &0.8.0-incubating& % &provided&,
&org.apache.hadoop& % &hadoop-client& % &2.0.0-cdh4.4.0& % &provided&
Maven defines&&as:
This is much like&compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scopeprovided&because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
2、Merge Strategy
如果在相对路径下,有多个相同的文件或者jar,这时我们可以使用Merge策略。
在build.sbt中对assemblyMergeStrategy&进行定义。
mergeStrategy in assembly &&= (mergeStrategy in assembly) { (old) =&
case PathList(&org&, &slf4j&, xs @ _*)
=& MergeStrategy.first
case PathList(ps @ _*) if ps.last endsWith &axiom.xml& =& MergeStrategy.filterDistinctLines
case PathList(ps @ _*) if ps.last endsWith &Log$Logger.class& =& MergeStrategy.first
case PathList(ps @ _*) if ps.last endsWith &ILoggerFactory.class& =& MergeStrategy.first
case x =& old(x)
解决方法:将org, slf4j 这个下的所有类和文件,都做合并, 采用的策略是:在classpath里,2选1,选的是classpath顺序里第一个self4j。
这里支持多种格式,例如ps.lat endsWith &axiom.xml& ,是以axiom.xml为结尾的文件,都采用filterDistinctLines策略,即合并两个文件,舍去重复的部分。
通过以上修改,终于解决了slf4j冲突的问题,即deduplicate: different file contents found in the following问题。
合并策略有很多种:
可以参考官方sbt assembly文档:
MergeStrategy.deduplicate&is the default described above
MergeStrategy.first&picks the first of the matching files in classpath order
MergeStrategy.last&picks the last one
MergeStrategy.singleOrError&bails out with an error message on conflict
MergeStrategy.concat&simply concatenates all matching files and includes the result
MergeStrategy.filterDistinctLines&also concatenates, but leaves out duplicates along the way
MergeStrategy.rename&renames the files originating from jar files
MergeStrategy.discard&simply discards matching files
更多的写法,example:
assemblyMergeStrategy in assembly := {
case PathList(&javax&, &servlet&, xs @ _*)
=& MergeStrategy.first
case PathList(ps @ _*) if ps.last endsWith &.html& =& MergeStrategy.first
case &application.conf&
=& MergeStrategy.concat
case &unwanted.txt&
=& MergeStrategy.discard
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
& 碰到类似的问题不要慌张,仔细看log描述的是什么意思。
& 异常报出内容冗余的冲突,在看路径,发现在classpath内有完全相同的2个类,这是导致问题的根本原因。
& 找出原因,解决方发,消除冲突两种方法,一直是去除法,另一种是合并法。
& 相对于maven和gradle,sbt的冲突解决方法还是比较接近底层。如果没记错的话,maven和gradle都能自动解决冲突。

我要回帖

更多关于 jar包冲突怎么解决 的文章

 

随机推荐