记遇见的一次AbstractMethodError
问题:
- Spring Cloud Version:Hoxton.SR3
- Spring Cloud Alibaba Version:2.2.0.RELEASE
项目中consumer端使用@FeignClient
定义接口,启动报错:
Caused by: java.lang.AbstractMethodError: com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata(Ljava/lang/Class;)Ljava/util/List;
at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:151) ~[feign-core-10.7.4.jar:na]
at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:49) ~[feign-core-10.7.4.jar:na]
分析:
Spring Cloud从Hoxton.SR1版本开始,依赖的spring-cloud-starter-openfeign
版本为2.2.2.RELEASE;
Spring Cloud Alibaba 2.2.0.RELEASE依赖的spring-cloud-openfeign-dependencies
版本为2.2.0.RELEASE;
feign的Contract
接口,
2.2.0.RELEASE:
// TODO: break this and correct spelling at some point
List<MethodMetadata> parseAndValidatateMetadata(Class<?> targetType);
2.2.2.RELEASE:
List<MethodMetadata> parseAndValidateMetadata(Class<?> targetType);
在2.2.0.RELEASE里有一行注释描述,接口方法名拼写错误,在2.2.2.RELEASE方法已修正了,即方法名发生了改变。
在spring-cloud-alibaba-sentinel
中的SentinelContractHolder
类,用到了该接口的这个方法(feign2.2.0.RELEASE版本):
@Override
public List<MethodMetadata> parseAndValidatateMetadata(Class<?> targetType) {
List<MethodMetadata> metadatas = delegate.parseAndValidatateMetadata(targetType);
metadatas.forEach(metadata -> METADATA_MAP
.put(targetType.getName() + metadata.configKey(), metadata));
return metadatas;
}
解决:
以下3中方式均可:
-
修改Spring Cloud版本,Hoxton.SR3改为Hoxton.RELEASE
-
在dependencyManagement中指定
spring-cloud-openfeign-dependencies
的版本为2.2.0.RELEASE
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
注意:spring-cloud-openfeign-dependencies
写在spring-cloud-dependencies
前面,因为dependency前面的优先生效。
- 在项目中相同包路径下新建
SentinelContractHolder
类,方法实现和spring-cloud-alibaba-sentinel
相同,修改Contract
接口为新版版本的方法名即可。
总结:
-
AbstractMethodError是ERROR的子类,不能在编译时检查出来,运行时才会触发
-
A依赖于B,运行时JVM发现B的class文件和编译时不一致会抛该异常,一般是因为B有多个版本,版本不兼容导致,比如方法签名变了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现