NoSuchMethodError: org.springframework.boot.web.servlet.error.최신 spring-cloud-starter-netflix-zuul의 ErrorController.getErrorPath()
내 애플리케이션은 spring-boot 버전 2.5.0과 spring-cloud-starter-netflix-zuul 2.2.8을 사용합니다.
최신 spring-boot 버전 2.5.0에서 getErrorPath() API가 ErrorController에서 제거되었지만 최신 spring-cloud-starter-netflix-zuul 2.2.8.RELEASE는 여전히 이 API를 호출하고 이 오류를 발생시킵니다.
동일한 문제가 발생하여 이미 해결된 사람이 있습니까?
2021-06-23 19:36:31 o.a.c.c.C.[.[localhost] [ERROR] Exception Processing ErrorPage[errorCode=0, location=/error]
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: 'java.lang.String org.springframework.boot.web.servlet.error.ErrorController.getErrorPath()'
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1078)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:106)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:87)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:710)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:398)
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:257)
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:352)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:177)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NoSuchMethodError: 'java.lang.String org.springframework.boot.web.servlet.error.ErrorController.getErrorPath()'
at org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping.lookupHandler(ZuulHandlerMapping.java:87)
at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.getHandlerInternal(AbstractUrlHandlerMapping.java:152)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:498)
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1257)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
... 72 common frames omitted
문제는 org.springframework.cloud:spring-cloud-starter-netflix-zuul:2.2.x와 SpringBoot 2.5.x 사이의 Spring 버전 충돌입니다.
여기에 언급된 알도봉지오의 해결 방법/수정 방법은 저에게 효과가 있었습니다. https://gist.github.com/aldobongio/6a22f49863c7a777612f7887bbb8fd1d
이 코드는 원래 ZuulHandlerMapping bean 주위에 사용자 지정 프록시를 래핑하는 새 BeanPostProcessor를 만듭니다.이 프록시는 lookupHandler 메서드의 호출을 차단하여 "NoSuchMethodError"로 이어지는 코드의 실행을 방지합니다.
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.cloud.netflix.zuul.web.ZuulController;
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Fix for Zuul configuration with Spring Boot 2.5.x + Zuul - "NoSuchMethodError: ErrorController.getErrorPath()":
*/
@Configuration
public class ZuulConfiguration {
/**
* The path returned by ErrorController.getErrorPath() with Spring Boot < 2.5
* (and no longer available on Spring Boot >= 2.5).
*/
private static final String ERROR_PATH = "/error";
private static final String METHOD = "lookupHandler";
/**
* Constructs a new bean post-processor for Zuul.
*
* @param routeLocator the route locator.
* @param zuulController the Zuul controller.
* @param errorController the error controller.
* @return the new bean post-processor.
*/
@Bean
public ZuulPostProcessor zuulPostProcessor(@Autowired RouteLocator routeLocator,
@Autowired ZuulController zuulController,
@Autowired(required = false) ErrorController errorController) {
return new ZuulPostProcessor(routeLocator, zuulController, errorController);
}
private enum LookupHandlerCallbackFilter implements CallbackFilter {
INSTANCE;
@Override
public int accept(Method method) {
if (METHOD.equals(method.getName())) {
return 0;
}
return 1;
}
}
private enum LookupHandlerMethodInterceptor implements MethodInterceptor {
INSTANCE;
@Override
public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if (ERROR_PATH.equals(args[0])) {
// by entering this branch we avoid the ZuulHandlerMapping.lookupHandler method to trigger the
// NoSuchMethodError
return null;
}
return methodProxy.invokeSuper(target, args);
}
}
private static final class ZuulPostProcessor implements BeanPostProcessor {
private final RouteLocator routeLocator;
private final ZuulController zuulController;
private final boolean hasErrorController;
ZuulPostProcessor(RouteLocator routeLocator, ZuulController zuulController, ErrorController errorController) {
this.routeLocator = routeLocator;
this.zuulController = zuulController;
this.hasErrorController = (errorController != null);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (hasErrorController && (bean instanceof ZuulHandlerMapping)) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ZuulHandlerMapping.class);
enhancer.setCallbackFilter(LookupHandlerCallbackFilter.INSTANCE); // only for lookupHandler
enhancer.setCallbacks(new Callback[] {LookupHandlerMethodInterceptor.INSTANCE, NoOp.INSTANCE});
Constructor<?> ctor = ZuulHandlerMapping.class.getConstructors()[0];
return enhancer.create(ctor.getParameterTypes(), new Object[] {routeLocator, zuulController});
}
return bean;
}
}
}
저는 2020년부터 봄구름이 주울을 지원하지 않기 때문에 같은 문제에 직면했습니다.
spring-cloud와 netflix-zuul은 다음 버전과 같이 제대로 작동할 것입니다.
spring-boot-starter-parent: 2.1.3.RELEASE
java.version: 1.8
spring-cloud.version: Greenwich.RELEASE
spring-cloud-starter-netflix-zuul: 2.1.0.RELEASE
spring-cloud-starter-netflix-eureka-client: 2.1.0.RELEASE
jackson-dataformat-xml: 2.9.9
spring-cloud-starter-netflix-eureka-server: 2.1.0.RELEASE
이 문제가 발생하는 이유는 무엇입니까?
- 이 문제는 2.5.x에서 zuul 및 리본이 스프링 부트 메인 채널에서 제거되었기 때문에 발생합니다.
이 문제를 어떻게 해결할 수 있을까요?
교체:
Zuul
(Api 게이트웨이) 기준Spring Cloud Gateway
그리고.Ribbon
(부하 분산 장치) 기준Spring Cloud Loadbalancer
이 블로그를 통해 지침을 얻을 수 있습니다. https://spring.io/blog/2018/12/12/spring-cloud-greenwich-rc1-available-now#spring-cloud-netflix-projects-entering-maintenance-mode@Configuration 주석을 사용하여 빈 만들기:
- 작성
ZuulConfiguration.java
클래스를 지정하고 다음 코드를 사용합니다.
@Configuration
public class ZuulConfiguration {
/** The path returned by ErrorContoller.getErrorPath() with Spring Boot < 2.5 (and no longer available on Spring Boot >= 2.5). */
private static final String ERROR_PATH = "/error";
/**
* Constructs a new bean post-processor for Zuul.
*
* @param routeLocator
* the route locator.
* @param zuulController
* the Zuul controller.
* @param errorController
* the error controller.
* @return the new bean post-processor.
*/
@Bean
public ZuulPostProcessor zuulPostProcessor(@Autowired RouteLocator routeLocator, @Autowired ZuulController zuulController,
@Autowired(required = false) ErrorController errorController) {
return new ZuulPostProcessor(routeLocator, zuulController, errorController);
}
private static final class ZuulPostProcessor implements BeanPostProcessor {
private final RouteLocator routeLocator;
private final ZuulController zuulController;
private final boolean hasErrorController;
ZuulPostProcessor(RouteLocator routeLocator, ZuulController zuulController, ErrorController errorController) {
this.routeLocator = routeLocator;
this.zuulController = zuulController;
this.hasErrorController = (errorController != null);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (hasErrorController && (bean instanceof ZuulHandlerMapping)) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ZuulHandlerMapping.class);
enhancer.setCallbackFilter(LookupHandlerCallbackFilter.INSTANCE); // only for lookupHandler
enhancer.setCallbacks(new Callback[] { LookupHandlerMethodInterceptor.INSTANCE, NoOp.INSTANCE });
Constructor<?> ctor = ZuulHandlerMapping.class.getConstructors()[0];
return enhancer.create(ctor.getParameterTypes(), new Object[] { routeLocator, zuulController });
}
return bean;
}
}
private static enum LookupHandlerCallbackFilter implements CallbackFilter {
INSTANCE;
@Override
public int accept(Method method) {
if ("lookupHandler".equals(method.getName())) {
return 0;
}
return 1;
}
}
private static enum LookupHandlerMethodInterceptor implements MethodInterceptor {
INSTANCE;
@Override
public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if (ERROR_PATH.equals(args[0])) {
/* by entering this branch we avoid the ZuulHandlerMapping.lookupHandler method to trigger the NoSuchMethodError */
return null;
}
return methodProxy.invokeSuper(target, args);
}
}
}
- 솔루션 링크 https://gist.github.com/aldobongio/6a22f49863c7a777612f7887bbb8fd1d
스프링 클라우드 버전을 다운그레이드하는 것으로 문제가 해결되었습니다.
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
속성도 아래와 같이 변경되었습니다.
zuul.routes.serviceone.path=/user/**
zuul.routes.serviceone.url=USERSERVICE
정보: 사용 중Spring boot version 2.6.1
,spring-cloud-starter-netflix-zuul 2.2.10.RELEASE
솔루션(새로운 솔루션)BeanPostProcessor
사용자 정의 프록시를 원본 주위에 감싼다.ZuulHandlerMapping
bean.)이 일렉트로베이브에 의해 게시되었으며, 잘 작동합니다!!!
언급URL : https://stackoverflow.com/questions/68100671/nosuchmethoderror-org-springframework-boot-web-servlet-error-errorcontroller-ge
'programing' 카테고리의 다른 글
휴지 상태에서 사용되지 않는 다중 HiLoPerTableGenerator를 TableGenerator로 대체하는 방법 (0) | 2023.07.11 |
---|---|
facet_wrap 레이블을 완전히 제거합니다. (0) | 2023.07.11 |
Git 자격 증명 도우미 - 암호 업데이트 (0) | 2023.07.06 |
ORA-01741: 잘못된 0-길이 식별자 (0) | 2023.07.06 |
헤더가 있는 vba를 사용하여 sql 쿼리 결과를 excel로 내보내기 (0) | 2023.07.06 |