高版本Spring_EhCacheFactoryBean报错-java_lang_NoSuchMethodError-org_springframework_cache_ehcache_EhCacheFactoryBean_setMaxEntriesLocalHeap(J)V的解决

2018年02月24日 99 字 教程整理


问题描述: 因项目技术需求,项目需要在原有低版本Spring-3.2.15.RELEASE+ehcache-2.4.4(同时包含Mybatis)框架的基础上,升级到较新的版本(4.1.0.RELEASE及以上,本文所选版本为Spring-5.0.4.RELEASE)。
更新Spring相关依赖文件后,启动项目。发现项目出现:

java.lang.NoSuchMethodError: org.springframework.cache.ehcache.EhCach
eFactoryBean.setMaxEntriesLocalHeap(J)V

报错。

具体如下:

0.1. 报错详情:找不到setMaxEntriesLocalHeap(…)方法

报错相关信息如下:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cache.ehcache.EhCacheFactoryBean]:
 Constructor threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework
.cache.ehcache.EhCacheFactoryBean.setMaxEntriesLocalHeap(J)V
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy
.instantiate(SimpleInstantiationStrategy.java:89)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1086)
... 192 more
Caused by: java.lang.NoSuchMethodError: org.springframework.cache.ehcache.EhCach
eFactoryBean.setMaxEntriesLocalHeap(J)V
    at org.springframework.cache.ehcache.EhCacheFactoryBean.<init>(EhCacheFa
ctoryBean.java:101)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstruct
orAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingC
onstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:1
47)
    ... 194 more

从报错信息提示来看,大意是说在org.springframework
.cache.ehcache.EhCacheFactoryBean
这个引用类下,使用了**setMaxEntriesLocalHeap(…)**方法,但这个方法在当前类中没有定义。

查阅相关网络资料发现,也有类似的少许项目出现过这样的问题,但目前暂未总结出一个有效的解决方案。而Stackoverflow上也只是提及可能因版本冲突或相关bean未定义(后续结果证明,不是这个原因):https://stackoverflow.com/questions/28167845/spring-ehcache-no-such-method-error

类似问题信息及讨论如下,这段讨论已经很接近最终的处理方案了:

0.2. 解决思路:查看报错类源码及其继承父类

在上图的讨论中有猜测说这个问题可能是Spring4.1版本的一个bug,但截至目前时间,Spring已经更新到5.0.4版本了。因此,这个问题出在Spring源码的可能性不大。

我们来查看一下报错所指的类及其相关代码:

在spring-context-support的jar包源码中,我们发现,在EhCacheFactoryBean的构造方法中,使用到了setMaxEntriesLocalHeap(10000);这一方法,而在这个类中,确实没有定义这个方法。

我们再来仔细查看整个类的全部代码,这里有一个非常重要的转折点:

在EhCacheFactoryBean这个类定义的时候,它继承了另一个类: CacheConfiguration

问题迎刃而解:


如果EhCacheFactoryBean这个类需要使用setMaxEntriesLocalHeap(…)这一方法,那么这个方法必须定义在EhCacheFactoryBean或CacheConfiguration类之一。


从这一步可以看出,在上一图的问题讨论中,这个思路已经非常接近正确的处理方案:

0.3. 解决方案:升级ehcache-core版本,由net.sf.ehcache.config.CacheConfiguration类提供setMaxEntriesLocalHeap(…)方法

在之前配置中,项目所用的ehcache-core依赖是2.4.4版本,我们查看net.sf.ehcache.config.CacheConfiguration这个类,发现确实没有定义setMaxEntriesLocalHeap(…)方法。

因此,目前可以推出结论:


高版本Spring-EhCacheFactoryBean所需setMaxEntriesLocalHeap(…)方法需由net.sf.ehcache.config.CacheConfiguration类提供,只要找到包含setMaxEntriesLocalHeap(…)方法的较高版本ehcache-core依赖即可。


也就是说,之前报错是因为Spring升级到4.1.0及更高版本之后,ehcache-core版本相对较低,不能提供响应方法支持所致。

因此,解决这个问题,只要相应的升级ehcache-core版本即可。查看ehcache-core版本历史发现,2.5.0及以上版本均可包含setMaxEntriesLocalHeap(…)方法。

接下来修改maven:ehcache-core版本至2.6.5,再重新启动项目即正常运行!

<!-- Spring4.1及以上版本在spring-context-support.jar包需用到setMaxEntriesLocalHeap()方法,因此echcahe-core需升级到2.5.0及以上版本 -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache-core</artifactId>
    <version>2.6.5</version>
</dependency>