alibaba / jetcache

JetCache is a Java cache framework.
Apache License 2.0
5.06k stars 1.05k forks source link

环境是jdk17,可以使用吗? #635

Open Apache001 opened 2 years ago

areyouok commented 2 years ago

你可以试试,有问题反馈,理论上应该没有问题

herodotus-ecosystem commented 2 years ago

你可以试试,有问题反馈,理论上应该没有问题

用的 Liberica JDK 17。运行就会报错误:

Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private volatile int java.util.concurrent.atomic.AtomicInteger.value accessible: module java.base does not "opens java.util.concurrent.atomic" to unnamed module @475d61e6
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) ~[na:na]
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) ~[na:na]
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178) ~[na:na]
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:172) ~[na:na]
    at com.esotericsoftware.kryo.serializers.CachedFields.addField(CachedFields.java:123) ~[kryo-5.3.0.jar:na]
    at com.esotericsoftware.kryo.serializers.CachedFields.rebuild(CachedFields.java:99) ~[kryo-5.3.0.jar:na]
    at com.esotericsoftware.kryo.serializers.FieldSerializer.<init>(FieldSerializer.java:82) ~[kryo-5.3.0.jar:na]
    at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.<init>(CompatibleFieldSerializer.java:57) ~[kryo-5.3.0.jar:na]
    at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.<init>(CompatibleFieldSerializer.java:53) ~[kryo-5.3.0.jar:na]
    ... 63 common frames omitted

应该是 Kryo 在 JDK 17 下面不兼容:

[Support for JDK17](https://github.com/EsotericSoftware/kryo/issues/885)

herodotus-ecosystem commented 2 years ago

用的 Kryo 5.3.0 + Spring Boot 2.7.0

一个解决办法:

  1. 增加 AtomicIntegerSerializer

    public class AtomicIntegerSerializer extends Serializer<AtomicInteger> {
    
    @Override
    public void write(Kryo kryo, Output output, AtomicInteger object) {
        output.writeString(String.valueOf(object.get()));
    }
    
    @Override
    public AtomicInteger read(Kryo kryo, Input input, Class<? extends AtomicInteger> type) {
        return new AtomicInteger(input.readInt());
    }
    }

2、修改 KryoValueEncoder

    static ThreadLocal<Object[]> kryoThreadLocal = ThreadLocal.withInitial(() -> {
        Kryo kryo = new Kryo();
        kryo.setDefaultSerializer(CompatibleFieldSerializer.class);
        kryo.setRegistrationRequired(false); // Kryo 5 默认修改为 true,不设置为false 会出现 CacheValueHolder 未注册错误
        kryo.register(AtomicInteger.class, new AtomicIntegerSerializer());
        kryo.setReferences(true);
//        kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
//        kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(new StdInstantiatorStrategy()));

        byte[] buffer = new byte[INIT_BUFFER_SIZE];

        WeakReference<byte[]> ref = new WeakReference<>(buffer);
        return new Object[]{kryo, ref};
    });