Open Apache001 opened 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)
用的 Kryo 5.3.0 + Spring Boot 2.7.0
一个解决办法:
增加 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};
});
你可以试试,有问题反馈,理论上应该没有问题