Я обновил одну из наших служб Spring Boot, чтобы она выглядела так в POM:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>io.pivotal.spring.cloud</groupId>
<artifactId>spring-cloud-services-dependencies</artifactId>
<version>1.5.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
смотреть это:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>io.pivotal.spring.cloud</groupId>
<artifactId>spring-cloud-services-dependencies</artifactId>
<version>1.6.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Теперь мы получаем следующую ошибку, когда пытаемся связаться с другой службой внутри Cloud Foundry.
Error creating bean with name 'ribbonRestClient' defined in org.springframework.cloud.netflix.ribbon.RestClientRibbonConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.netflix.niws.client.http.RestClient]: Factory method 'ribbonRestClient' threw exception; nested exception is java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig
Мы развертываем наш сервис в локальном Pivotal Cloud Foundry и используем сервис Service Registry, встроенный в PCF («плитку»).
Я предполагаю, что у меня где-то испорченная конфигурация, но я не могу понять, где.
Я также думаю, что это напрямую связано с этим коммитом, но я не могу найти разрешение: github коммит
2018-04-09_20:05:42.590 ERROR org.apache.juli.logging.DirectJDKLog.log ln182 Message: Servlet.service() for servlet [dispatcherServlet] in context with path [/api/v1] threw exception [Request processing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ribbonRestClient' defined in org.springframework.cloud.netflix.ribbon.RestClientRibbonConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.netflix.niws.client.http.RestClient]: Factory method 'ribbonRestClient' threw exception; nested exception is java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig] with root cause
java.lang.ClassNotFoundException: com.sun.jersey.api.client.config.ClientConfig
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:94)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.springframework.cloud.netflix.ribbon.RestClientRibbonConfiguration.ribbonRestClient(RestClientRibbonConfiguration.java:58)
at org.springframework.cloud.netflix.ribbon.RestClientRibbonConfiguration$$EnhancerBySpringCGLIB$$4a284cff.CGLIB$ribbonRestClient$0(<generated>)
at org.springframework.cloud.netflix.ribbon.RestClientRibbonConfiguration$$EnhancerBySpringCGLIB$$4a284cff$$FastClassBySpringCGLIB$$ab36db6.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
at org.springframework.cloud.netflix.ribbon.RestClientRibbonConfiguration$$EnhancerBySpringCGLIB$$4a284cff.ribbonRestClient(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:220)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1018)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345)
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:89)
at org.springframework.cloud.netflix.ribbon.SpringClientFactory.getInstance(SpringClientFactory.java:110)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1092)
at org.springframework.cloud.context.named.NamedContextFactory.getInstance(NamedContextFactory.java:124)
at org.springframework.cloud.netflix.ribbon.SpringClientFactory.getClient(SpringClientFactory.java:51)
at org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactory.createRequest(RibbonClientHttpRequestFactory.java:51)
at <custom>.RequestCorrelationClientHttpRequestInterceptor.intercept(RequestCorrelationClientHttpRequestInterceptor.java:61)
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:86)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:70)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:660)
at org.springframework.cloud.netflix.metrics.MetricsClientHttpRequestInterceptor.intercept(MetricsClientHttpRequestInterceptor.java:64)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at <custom>.JwtForwardingClientHttpRequestInterceptor.intercept(JwtForwardingClientHttpRequestInterceptor.java:53)
at org.springframework.web.client.RestTemplate$$FastClassBySpringCGLIB$$aa4e9ed0.invoke(<generated>)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at org.springframework.cloud.netflix.metrics.RestTemplateUrlTemplateCapturingAspect.captureUrlTemplate(RestTemplateUrlTemplateCapturingAspect.java:33)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:621)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:320)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.web.client.RestTemplate$$EnhancerBySpringCGLIB$$2ffd02d3.getForEntity(<generated>)
at <custom>.Controller.doStuff(Controller.java:45)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at <custom>.Service.doStuff(Service.java:25)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter(MDCInsertingServletFilter.java:49)
at <custom>.doFilter(Filter.java:56)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:677)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.lang.Thread.run(Thread.java:748)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.cloudfoundry.router.ClientCertificateMapper.doFilter(ClientCertificateMapper.java:77)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
Отредактировано, чтобы включить трассировку стека и деревья зависимостей maven.
@AndyWilkinson - Добавлена трассировка стека для каждого запроса
Это автоматическая конфигурация для ленты, использующей Jersey. Это не должно быть связано с коммитом, который вы связали с Eureka. Какие зависимости есть у вашего приложения? Будет полезен вывод mvn dependency:tree до и после обновления.
@AndyWilkinson - добавлена ссылка на gists с деревьями зависимостей maven
Вы были правы, подозревая это коммит.
В вашем исходном pom зависимость от io.pivotal.spring.cloud:spring-cloud-services-starter-service-registry привела к транзитивной зависимости от jersey-client:
+- io.pivotal.spring.cloud:spring-cloud-services-starter-service-registry:jar:1.5.0.RELEASE:compile
| +- org.springframework.cloud:spring-cloud-starter-eureka:jar:1.3.6.RELEASE:compile
| | +- org.springframework.cloud:spring-cloud-starter:jar:1.2.5.RELEASE:compile
| | | +- org.springframework.cloud:spring-cloud-context:jar:1.2.5.RELEASE:compile
| | | | \- org.springframework.security:spring-security-crypto:jar:4.2.3.RELEASE:compile
| | | +- org.springframework.cloud:spring-cloud-commons:jar:1.2.5.RELEASE:compile
| | | \- org.springframework.security:spring-security-rsa:jar:1.0.3.RELEASE:compile
| | | \- org.bouncycastle:bcpkix-jdk15on:jar:1.55:compile
| | | \- org.bouncycastle:bcprov-jdk15on:jar:1.55:compile
| | +- org.springframework.cloud:spring-cloud-netflix-core:jar:1.3.6.RELEASE:compile
| | +- org.springframework.cloud:spring-cloud-netflix-eureka-client:jar:1.3.6.RELEASE:compile
| | +- com.netflix.eureka:eureka-client:jar:1.6.2:compile
| | | +- org.codehaus.jettison:jettison:jar:1.3.7:runtime
| | | | \- stax:stax-api:jar:1.0.1:runtime
| | | +- com.netflix.netflix-commons:netflix-eventbus:jar:0.3.0:runtime
| | | | +- com.netflix.netflix-commons:netflix-infix:jar:0.3.0:runtime
| | | | | +- commons-jxpath:commons-jxpath:jar:1.3:runtime
| | | | | +- joda-time:joda-time:jar:2.9.9:runtime
| | | | | +- org.antlr:antlr-runtime:jar:3.4:runtime
| | | | | | +- org.antlr:stringtemplate:jar:3.2.1:runtime
| | | | | | \- antlr:antlr:jar:2.7.7:runtime
| | | | | \- com.google.code.gson:gson:jar:2.8.1:runtime
| | | | \- org.apache.commons:commons-math:jar:2.2:runtime
| | | +- com.netflix.archaius:archaius-core:jar:0.7.4:compile
| | | +- javax.ws.rs:jsr311-api:jar:1.1.1:runtime
| | | +- com.netflix.servo:servo-core:jar:0.10.1:runtime
| | | | \- com.netflix.servo:servo-internal:jar:0.10.1:runtime
| | | +- com.sun.jersey:jersey-core:jar:1.19.1:runtime
| | | +- com.sun.jersey:jersey-client:jar:1.19.1:runtime
| | | +- com.sun.jersey.contribs:jersey-apache-client4:jar:1.19.1:runtime
| | | \- com.google.inject:guice:jar:4.1.0:runtime
| | | \- javax.inject:javax.inject:jar:1:runtime
jersey-client также является транзитивной зависимостью org.springframework.cloud:spring-cloud-starter-netflix-ribbon, которую втягивает org.springframework.cloud:spring-cloud-starter-netflix-eureka-client.
Исключение, которое было добавлено в коммите, указанном выше, привело к тому, что jar-файлы Jersey были полностью исключены, хотя Ribbon зависит от них. Вы должны иметь возможность обойти проблему, добавив явную зависимость от
org.springframework.cloud:spring-cloud-starter-netflix-ribbon без исключений. Однако я не думаю, что вам это необходимо.
Я бы открыл вопрос против Начинающие с Spring Cloud Services, поскольку похоже, что исключение может быть слишком широким. Либо это, либо не предполагается, что люди используют Ribbon так же, как вы при использовании этого стартера.
ОК. Я пойду и открою вопрос. Спасибо за подтверждение и предложение обойтись.
Для будущих читателей эта проблема возникает при настройке Ribbon для использования устаревшего RestClient. См. Проблема Spring Cloud Services Starters для дальнейшего объяснения.
Какая полная трассировка стека ошибки? Было бы полезно знать, какой код ожидает, что
jersey-clientбудет в пути к классам.