springboot3 引入 kryo-serializers

99 阅读1分钟

调用公司的一个老dubbo接口,发现报错(好像是这个)

Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.alibaba.dubbo.common.serialize.support.kryo.utils.KryoUtils

在网络上查阅资料后发现是由于缺少了 kryo-serializers 依赖,引入依赖

<!-- Kryo 序列化-->
<dependency>
  <groupId>com.esotericsoftware.kryo</groupId>
  <artifactId>kryo</artifactId>
  <version>2.24.0</version>
</dependency>
<dependency>
  <groupId>de.javakaffee</groupId>
  <artifactId>kryo-serializers</artifactId>
  <version>0.41</version>
</dependency>

注意 kryo 与 kryo-serializers的版本号,kryo-serializers 从2019年便已停止更新,与之后的 kryo 版本不再兼容。

引入之后发现项目无法启动,于是查找依赖冲突,发现redisson-spring-boot-starter中已有很新版本的 kryo,而此版本无适配的 kryo-serializers。

查阅资料后发现 redisson 默认将 kryo 作为了 codec(主要负责对象的序列化和反序列化),于是想到“如果更改codec的实现或许就不会再产生冲突了”。

尝试在 nacos 配置文件中更改 codec 实现,然而不知道是什么原因,更改一直无法生效(网上找到的方法全部无效),于是直接在项目手写 redisson 配置类。

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.redisson.Redisson;
import org.redisson.config.SingleServerConfig;
import org.redisson.config.TransportMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class RedissonConfig {

    @Value("${spring.data.redis.host}")
    private String hostName;

    @Value("${spring.data.redis.port}")
    private String port;

    @Value("${spring.data.redis.password}")
    private String password;

    @Value("${spring.data.redis.database}")
    private Integer database;

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        SingleServerConfig singleServerConfig = config.useSingleServer();
        singleServerConfig.setAddress("redis://" + hostName + ":" + port);
        singleServerConfig.setDatabase(database);
        if (StringUtils.isNotEmpty(password)) {
            singleServerConfig.setPassword(password);
        }
        singleServerConfig.setPingConnectionInterval(60 * 1000);
        singleServerConfig.setConnectionMinimumIdleSize(5);
        singleServerConfig.setConnectionPoolSize(10);
        config.setCodec(new JsonJacksonCodec());
        config.setTransportMode(TransportMode.NIO);
        return Redisson.create(config);
    }
}

配置成功生效,也成功避免了项目启动时 redisson 对 kryo 的依赖导致的冲突。