-
Notifications
You must be signed in to change notification settings - Fork 8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] NoSuchMethodError: 'org.springframework.web.reactive.function.server.ServerResponse$BodyBuilder #3298
Comments
同问,在JDK17+spring-cloud-starter-alibaba-sentinel 2022.0.0.0-RC2下,当触发限流时会导致com.alibaba.csp.sentinel.adapter.spring.webflux.callback.DefaultBlockRequestHandler#htmlErrorResponse报错java.lang.NoSuchMethodError: 'org.springframework.web.reactive.function.server.ServerResponse$BodyBuilder org.springframework.web.reactive.function.server.ServerResponse.status(org.springframework.http.HttpStatus)' |
遇到相同问题 或者也可以通过自定义逻辑处理被限流的请求(不使用默认的DefaultBlockRequestHandler)来解决此问题 @Configuration
public class SentinelConfig {
public SentinelConfig() {
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable ex) {
return ServerResponse.ok().body(Mono.just("限流啦,请求太频繁"), String.class);
}
});
}
} |
@zhuomuniao1986 请教下为什么使用JDK17重新编译就可以,是因为 Spring 限制么? |
今天再次试了一下,发现直接用JDK17重新编译sentinel-spring-cloud-gateway-adapter-1.8.6是不行的,估计是因为DefaultBlockRequestHandler中使用到的ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)在不同版本中参数类型不一样导致的,在spring-webflux:6.0.4中ServerResponse.status(HttpStatusCode status)方法需要的是HttpStatusCode,而这里传入的是HttpStatus,所以在spring-webflux:6.0.4中ServerResponse没有找到对应的方法。 |
@zhuomuniao1986 但HttpStatus实现了HttpStatusCode接口。 |
是的,但是可能是因为DefaultBlockRequestHandler中使用到的ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)中的HttpStatus还是老的(未实现接口) 下面是我对这个问题的简单复现 新建项目A,模拟spring中的ServerResponse和HttpStatus
新建项目B,模拟alibaba中的DefaultBlockRequestHandler,在handleRequest方法中调用项目A的ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS);
新建项目C,调用项目B中的方法进行测试
这时测试输出正常。 接下来,修改项目A,升级一个新的版本: 新建接口
修改枚举类,实现上面的接口
修改ServerResponse status的入参为HttpStatusCode接口
然后在项目C中引用项目A的新版本,这时再运行就报错NoSuchMethodError 注:以上所有项目都在jdk17下进行。 |
@zhuomuniao1986 恩,现在的问题应该就是Sentinel需要依赖 Spring6 然后重新编译一下就可以了。 |
是的。 拿上面的简单复现进行分析,发现 可以看出,右边去调用ServerResponse.status的参数类型为HttpStatus方法,这个在项目A的新版本中是不存在的,所以报NoSuchMethodError错误;而左边是调用ServerResponse.status的参数类型为HttpStatusCode的方法,这个在项目A的新版本中是存在的,所以不报错了。 |
Issue Description
Type: bug report
Describe what happened
Describe what you expected to happen
How to reproduce it (as minimally and precisely as possible)
触发限流后 报异常 NoSuchMethodError 感觉是依赖版本适配问题 senintel的gateway插件对新版本gateway适配有问题
Tell us your environment
Anything else we need to know?
The text was updated successfully, but these errors were encountered: