欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【开发笔记】Spring MVC框架升级错误:找不到ReflectionUtils.doWithLocalFields方法

程序员文章站 2024-03-24 19:38:22
...

问题

在升级Spring MVC项目版本(目标版本是4.3.16)后,启动Tomcat输出如下错误信息:

ERROR | Context initialization failed
java.lang.NoSuchMethodError: org.springframework.util.ReflectionUtils.doWithLocalFields(Ljava/lang/Class;Lorg/springframework/util/ReflectionUtils$FieldCallback;)V
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.buildPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:418)
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:397)
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:333)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:929)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:220)
	at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:619)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:465)
	at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4745)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5207)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

分析

通过搜索【doWithLocalFields java.lang.NoSuchMethodError】,得到类似的条目有:

(1)https://*.com/questions/46056321/spring-java-lang-nosuchmethoderror-org-springframework-util-reflectionutils-dow

(2)https://www.cnblogs.com/sxdcgaq8080/p/8022121.html(参考(1)中的结论:4.2以后上面报错的方法就被提到了spring-core架包中而不是在orm架包中,所以,需要将spring-orm架包的版本降低到<4.2以下)

(3)https://bbs.csdn.net/topics/392078670?page=1(仅提问,未解决)

搜到的条目并不是很多,看来并不是很多开发者倾向于升级框架版本(虽然最新的Spring框架版本都到了5.0+)。

虽然看完(1)和(2)感觉结论并不靠谱,并不会是4.2版本这个梗。

显而易见,框架是整体的,不可能就其中的某一个jar包为低版本吧?!

即便这样,(3)中的一个操作点醒了我,决定查看一下这个工具类的定义看看。

发现

在eclipse中使用快捷键Ctrl+Shift+t,检索ReflectionUtils这个工具类的引用,结果是大吃一惊!

【开发笔记】Spring MVC框架升级错误:找不到ReflectionUtils.doWithLocalFields方法

如上图,居然发现有2个该类的定义!其中1个类定义居然在Active MQ的jar包中

再搜索doWithLocalFields ActiveMQ,得到类似的条目:

(1)https://www.oschina.net/question/2670896_2242950(但没有得到解决方法)

问题定位在ActiveMQ的jar包中,打开该jar包,果不其然:

【开发笔记】Spring MVC框架升级错误:找不到ReflectionUtils.doWithLocalFields方法

顿时有2个疑问:

(1)为啥ActiveMQ的jar包中包含了Spring框架的代码?

(2)为啥旧版的ActiveMQ的jar包没有出现这个问题?

在ActiveMQ的官网上(http://activemq.apache.org/)似乎找到了根源:

从5.12.0版本开始,ActiveMQ的jar包中开始包含spring框架的部分代码(部分工具类),其中的代码是否与Spring官方发布的代码是否同步就不由得知了。

解决

使用ActiveMQ的5.12版之前的最后版本(5.11.4)替换较新5.14.5版本。

总结

(1)该问题属于jar包冲突的问题

(2)对于(1)需要进一步了解冲突类/接口的定义、引用情况,记住使用快捷键Ctrl+Shift+t

(3)不要一口气全部替换,可以分步替换,这样可以快速定位。