乐趣区

关于java:我服了SpringBoot升级后这服务我一个星期都没跑起来下

上一次的降级过程中差不多曾经跑起来 90% 了,这周一下班解决完一点小问题,服务曾经失常跑起来了,于是再拿着一些其余的服务测试了一下,又发现了一些其余的报错,所以持续。

14. DiscoveryEnabledServer Not Found

次要问题还是 eureka 中没有了 ribbon 相干的依赖。

Caused by: java.lang.NoClassDefFoundError: com/netflix/niws/loadbalancer/DiscoveryEnabledServer
    at java.lang.Class.getDeclaredMethods0(Native Method) ~[?:?]
    at java.lang.Class.privateGetDeclaredMethods(Class.java:3167) ~[?:?]
    at java.lang.Class.getDeclaredMethods(Class.java:2310) ~[?:?]
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:467) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321) ~[spring-core-5.3.23.jar:5.3.23]

解决方案:手动引入相干依赖包。

<dependency>
  <groupId>com.netflix.ribbon</groupId>
  <artifactId>ribbon-loadbalancer</artifactId>
  <version>2.7.18</version>
</dependency>
<dependency>
  <groupId>com.netflix.ribbon</groupId>
  <artifactId>ribbon-eureka</artifactId>
  <version>2.7.18</version>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  <version>2.2.10.RELEASE</version>
</dependency>

15. 中间件循环依赖

仍然是循环依赖报错,之前没留神看代码,简略的设置了一下为提早初始化,认真一看发现代码这样写的,你细品。

而后启动报错:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cachesEndpoint' defined in class path resource [org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfiguration.class]: Unsatisfied dependency expressed through method 'cachesEndpoint' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
Requested bean is currently in creation: Is there an unresolvable circular reference?

16. CacheMetricsRegistrarConfiguration 报错

因为在解决 15 的问题一开始是设置为提早初始化,而后启动发现依然报错。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsRegistrarConfiguration': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsRegistrarConfiguration]: Constructor threw exception; nested exception is java.lang.StackOverflowError

解决方案:去掉 Autowired 注入,15 和 16 的问题全副解决。

17. kafka-clients 版本和 spring-kafka 不兼容

降级后默认 spring-kafka 是 2.8.10 版本,KafkaTemplate 报错找不到类,起因在于本地 kafka-clients 应用的是 2.3.0 版本。

Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.kafka.core.KafkaTemplate] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@9e89d68]
Caused by: java.lang.NoClassDefFoundError: org/apache/kafka/clients/consumer/ConsumerGroupMetadata

解决方案:kafka-clients降级到兼容版本 3.0.2,这个版本是 spring-cloud-dependency 中依赖的版本。

18. swagger 启动报错

这个报错是因为新版本 Spring Boot 将 Spring MVC 默认门路匹配策略由 AntPathMatcher 改成了PathPatternParser,这个报错在我这里是 WARN,而且十分荫蔽,须要认真查找。

[WARN] [2022.11.08 16:17:39.963] [10.135.0.95] [] [main] [org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext()] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException

解决方案:配置成原来的AntPathMatcher,增加配置spring.mvc.pathmatch.matching-strategy= ANT_PATH_MATCHER

这个报错信息是一行 WARN 日志,十分难找,另外起因是依据网上信息搜寻定位到的,这个报错信息我真的服了。

19. spring-session 依赖报错

启动报错信息:

n attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.springframework.boot.autoconfigure.session.SessionAutoConfiguration$ServletSessionConfiguration.cookieSerializer(SessionAutoConfiguration.java:109)

The following method did not exist:

    'void org.springframework.session.web.http.DefaultCookieSerializer.setSameSite(java.lang.String)'

The calling method's class, org.springframework.boot.autoconfigure.session.SessionAutoConfiguration$ServletSessionConfiguration, was loaded from the following location:

    jar:file:/Users/user/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.7.5/spring-boot-autoconfigure-2.7.5.jar!/org/springframework/boot/autoconfigure/session/SessionAutoConfiguration$ServletSessionConfiguration.class

The called method's class, org.springframework.session.web.http.DefaultCookieSerializer, is available from the following locations:

    jar:file:/Users/user/.m2/repository/org/springframework/session/spring-session/1.3.5.RELEASE/spring-session-1.3.5.RELEASE.jar!/org/springframework/session/web/http/DefaultCookieSerializer.class

spring-session应用的是 1.3.5.RELEASE,然而关上 Maven 仓库一看,这竟然是最新版本?而且还是 2019 年的版本?

其实并非如此,查找 Github 代码后发现是代码做了模块化拆分,新版本应该引入spring-session-core

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-core</artifactId>
    <version>2.7.0</version>
</dependency>

20. spring-security 版本兼容问题

在看到 SessionAutoConfiguration外面代码同时发现 spring-security 相干依赖代码产生了扭转。

解决方案:引入最新版本spring-security-web

<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-web</artifactId>
  <version>5.7.4</version>
</dependency>

21. RibbonLoadBalancerClient 启动报错

报错信息:

org.springframework.retry.RetryException: Could not recover; nested exception is java.lang.AbstractMethodError: Receiver class org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient does not define or inherit an implementation of the resolved method abstract choose(Ljava/lang/String;Lorg/springframework/cloud/client/loadbalancer/Request;)Lorg/springframework/cloud/client/ServiceInstance; of interface org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser.

起因在于位于 spring-cloud-commons 外面的 ServiceInstanceChooser#choose 办法产生了扭转。

而咱们因为为了持续应用 spring-cloud-netflix-ribbon 包,引入的只能是更新到 2021 年的最新版本 2.2.10.RELEASE,这个包最初更新工夫是 2021 年 11 月份,所以这外面实现的依然是老的choose 办法。

解决方案:应用同 package 名形式本人重写该类,choose 办法的逻辑其实是和原来传参 object 办法一样的,或者本人把包拉下来改代码从新打包。

22. MongoDB 报错

spring-boot-autoconfigure新版本下 MongoClientFactory 构造函数产生扭转,以前的写法产生编译谬误。

以前的这种写法传参是MongoProperties

return new MongoClientFactory(mongoProperties).createMongoClient(mongoClientOptions());

当初的写法:

MongoClientSettingsBuilderCustomizer customizer = new MongoPropertiesClientSettingsBuilderCustomizer(mongoProperties, environment);
return new MongoClientFactory(Lists.newArrayList(customizer)).createMongoClient(mongoClientOptions());

另外一个问题是原来的 createMongoClient 传参是 MongoClientOptions,当初是 MongoClientSettings。

原来应用 heartbeatFrequencyheartbeatConnectTimeout 等等一些写法也不一样了,示意一下当初的写法:

MongoClientSettings.builder()
  .applyToServerSettings(builder -> builder.heartbeatFrequency(8000, TimeUnit.MILLISECONDS))
  .applyToConnectionPoolSettings(builder -> builder.maxConnectionIdleTime(30000,TimeUnit.MILLISECONDS))
  .applyToSocketSettings(builder -> builder.connectTimeout(30000,TimeUnit.MILLISECONDS))
  .build();

另外,如果应用到了 morphia 的话,这个改变就更大了,根本老代码没法用了,尝试了一下,改不动,临时放弃了。

总结

事件根本到这里就临时告一段落了,有一些老的代码改变太大,根本要废除重写了,临时搁置吧。

退出移动版