maven包冲突(java.lang.NoSuchMethodError)解决

标签:
mavenjar包冲突nosuchmethoderror |
分类: J2SE |
在Java项目开发时一般会使用maven作为项目jar包依赖管理工具,但随着工程依赖的jar包越来越多,“jar包冲突”这个潜在隐患随时可能爆发出来。大部分情况下,我们都会见到“java.lang.NoSuchMethodError”异常信息,这种情况八成都是由于包冲突引起的,如果熟悉了的话处理起来也是有法可循的,下面本文介绍一下常用方法和步骤。
产生原因
首先新说明一下为什么会出现“包冲突”:只会发生在package和路径一致的情况下,出现了一个相同的一个java类,但这个两个或多个java类隶属不是同的jar包中,导致应用在启动或运行时加载到了“错误”类,抛出异常堆栈信息。
问题示例
下面我们来看一个包冲突示例的异常堆栈信息:
-
2016-09-17
20:51:18,788 ERROR context.ContextLoader - Context initialization failed -
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'pullService': Invocation of init method failed; nested exception is V -
at org.springframework.beans.factory.support.AbstractAutowireCapableB eanFactory.initializeBean(AbstractAutowireCapableB eanFactory.java:1338) -
at org.springframework.beans.factory.support.AbstractAutowireCapableB eanFactory.doCreateBean(AbstractAutowireCapableB eanFactory.java:473) -
at org.springframework.beans.factory.support.AbstractAutowireCapableB eanFactory$1.run(AbstractAutowireCapableB eanFactory.java:409) -
at -
at org.springframework.beans.factory.support.AbstractAutowireCapableB eanFactory.createBean(AbstractAutowireCapableB eanFactory.java:380) -
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264) -
at org.springframework.beans.factory.support.DefaultSingletonBeanRegi stry.getSingleton(DefaultSingletonBeanRegi stry.java:222) -
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261) -
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185) -
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164) -
at org.springframework.beans.factory.support.DefaultListableBeanFacto ry.preInstantiateSingletons (DefaultListableBeanFacto ry.java:429) -
at org.springframework.context.support.AbstractApplicationConte xt.finishBeanFactoryInitial ization(AbstractApplicationConte xt.java:728) -
at org.springframework.context.support.AbstractApplicationConte xt.refresh(AbstractApplicationConte xt.java:380) -
at org.springframework.web.context.ContextLoader.createWebApplicationCont ext(ContextLoader.java:255) -
at org.springframework.web.context.ContextLoader.initWebApplicationContex t(ContextLoader.java:199) -
at com.alibaba.citrus.webx.context.WebxComponentsLoader.initWebApplicationContex t(WebxComponentsLoader.java:117) -
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45) -
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973) -
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467) -
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) -
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) -
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) -
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632) -
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1247) -
at com.cc.tomcat.container.host.AliHostConfig.deployDirectory(AliHostConfig.java:178) -
at com.cc.tomcat.container.host.AliHostConfig.deployApps(AliHostConfig.java:85) -
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1614) -
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:330) -
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117) -
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90) -
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:402) -
at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:347) -
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1140) -
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:799) -
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) -
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559) -
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549) -
at java.util.concurrent.FutureTask.run(FutureTask.java:262) -
at java.util.concurrent.AbstractExecutorService$2.run(AbstractExecutorService.java:120) -
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) -
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) -
at java.lang.Thread.run(Thread.java:745) -
Caused
by: V -
at com.cc.citrus.util.internal.DynamicClassBuilder.getSignature(DynamicClassBuilder.java:54) -
at com.cc.citrus.util.internal.StaticFunctionDelegatorB uilder.addMethod(StaticFunctionDelegatorB uilder.java:78) -
at com.cc.citrus.util.internal.StaticFunctionDelegatorB uilder.addMethod(StaticFunctionDelegatorB uilder.java:71) -
at com.cc.citrus.util.internal.StaticFunctionDelegatorB uilder.addClass(StaticFunctionDelegatorB uilder.java:63) -
at com.alibaba.citrus.util.Utils.createMixin(Utils.java:84) -
at com.alibaba.citrus.util.Utils.<clinit>(Utils.java:47) -
at com.cc.citrus.service.pull.support.UtilToolSet.getToolNames(UtilToolSet.java:35) -
at com.cc.citrus.service.pull.impl.PullServiceImpl.initToolFactories(PullServiceImpl.java:182) -
at com.cc.citrus.service.pull.impl.PullServiceImpl.init(PullServiceImpl.java:103) -
at com.cc.citrus.springext.support.BeanSupport.afterPropertiesSet(BeanSupport.java:80) -
at org.springframework.beans.factory.support.AbstractAutowireCapableB eanFactory.invokeInitMethods(AbstractAutowireCapableB eanFactory.java:1369) -
at org.springframework.beans.factory.support.AbstractAutowireCapableB eanFactory.initializeBean(AbstractAutowireCapableB eanFactory.java:1335) -
... 41 more
解决方法和步骤
1. 查看异常堆栈信息
堆栈信息很长,但基本有两部分内容:一是运行时抛出的错误信息;二是“Caused by”后面的具体原因说明。
我们主要看第二部分(Caused by: java.lang.NoSuchMethodError: net.sf.cglib.core.Signature.<init>(LV)这些信息。
2. 分析冲突类
从异常堆栈信息中可以明显看出是“Signature”这个类出了问题,然后再IDE中查询出这个类都在哪些类中。
以IntelliJ IDEA为例,在应用中双击“shit”键即可看到该类在哪些包中,搜索的时候记得带上完整的包路径名称,即“net.sf.cglib.core.Signature”,搜索结果如下:
http://dl2.iteye.com/upload/attachment/0120/0676/7723ac20-89c5-3e9e-ad05-f00aded797c5.jpg
我们可以明显的看出,“net.sf.cglib.core.Signature”这个类存在于两jar包中,cglib-nodep:2.2.2和cglib:2.2.2。
3.确定冲突jar包
找个了冲突的两个包后,我们就要接着分析是哪个包引起的冲突,以及需要保留哪个去除掉哪个。
这时候就需要接着看之前的异常堆栈信息了:
-
at
com.alibaba.citrus.util.internal.DynamicClassBuilder.getSignature(DynamicClassBuilder.java:54)
-
protected
Signature getSignature(Method method, String rename) { -
String name = defaultIfNull(trimToNull(rename), method.getName()); -
Type returnType = Type.getType(method.getReturnType()); -
Type[] paramTypes = Type.getArgumentTypes(method); -
-
return new Signature(name, returnType, paramTypes); -
}
http://dl2.iteye.com/upload/attachment/0120/0680/65a7766d-bc05-3fa5-834c-853b717a1626.jpg
4.排除冲突的包
冲突jar包定位到了之后,我们就需要再maven工程的pom.xml文件中将冲突jar给排除掉,使用“exclusion”命令即可:
-
<</span>exclusions>
-
<</span>exclusion> -
<</span>groupId>cglib</</span>groupId> -
<</span>artifactId>cglib</</span>artifactId> -
</</span>exclusion> -
</</span>exclusions>
5. 结果验证
最后一步重新编译web工程,更新maven工程依赖jar包,重新启动工程,验证问题是否解决。