java.lang.ExceptionInInitializerError解决办法

我仅仅是在Junit代码中执行了如下一行代码,竟然抛出了异常,我震惊了,  我只是构造了一个对象啊

 

DefaultHttpClient client = new DefaultHttpClient();

于是我跟踪该构造函数,最后发现是在如下代码处抛出的异常:

 

 

private final Log log = LogFactory.getLog(getClass());


异常信息如下:

 

在targetd exception的发现如下信息:

 

java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.


分析原因:

 

原因已经很明显,是jar包冲突引起的,应该是jvm在加载的过程中加载了错误的log4j,而恰好不是我上面用到的,从而导致代码执行到上述位置时发现LogFactory还并没有加载初始化,导致异常。

解决办法:

解决方案也很显然了,去掉其中一个jar包,问题马上就可以得到解决。

 

此外我也查了很多资料,jar包冲突会出现很多莫名其妙的问题:下面的介绍也许对大家有用。

 

JAR包冲突解决方法

问题表现

系统原来可以运行, 但是引入某个jar包(为了调用某个服务)后, 所有配置/参数都正确, 但是却运行不起来, 或者报找不到类, 找不到方法等异常!
java类找不到 java.lang.ClassNotFoundException
方法不存在 java.lang.NoSuchMethodError
字段不存在 java.lang.NoSuchFieldError
类错误 java.lang.LinkageError
表面原因

war包中jar包和服务器上jar包冲突, 由于现在服务器功能越来越强大, 而引入的jar也在不断增加, 出现的冲突的可能性也越来越大, 而且正式环境复杂, 而且不能轻易修改服务器相关配置
根本原因

同一个java类存在多个jar包或类路径中, 而这大多由于使用了不同jar包版本造成.
maven管理jar包, 如果同一个Jar有多个版本是根据最短路径拉取jar包的
同一个package出现在多个jar包里面, 怎么处理?
简单的处理方法

根据报错的class名或方法名定位到可能导致冲突的jar包,jar包冲突引入有几种情况:
引入了这个jar包的多个版本,而mvn仲裁的时候取了错误的版本,这个版本本身就缺少正确的class或方法。
引入了不同坐标但是具有同名class的多个jar,mvn加载class的顺序差异会导致加载到错误的class。
通过mvn dependency:tree > tree.txt 导出全部的依赖。 可以使用 -Dverbose 、-Dincludes或者-Dexcludes参数来精确定位导致冲突的jar包。
找到需要排除的依赖jar包,通过mvn仲裁优先的方法定义正确的jar包,或者通过exclusion的方式排除错误的jar包。
温馨提示:另外在项目开发中jar尽量按需引入,系统管理起来,别什么都不管直接加包进来,这样也可以在一定程度上减少jar包冲突的风险。
避免技巧

为了减少jar包冲突, 特别是一些底层jar包, 根据最短路径方法: 最好人工指定版本, 并使用dependencyManage

 

 

 

 

 

 

你可能感兴趣的:(Java)