From 34759aaf139016623d0b7a8664af36714480e2b8 Mon Sep 17 00:00:00 2001 From: Shawn Date: Tue, 10 Oct 2023 21:29:41 +0800 Subject: [PATCH] [Java] fix jit error for register private serializers (#999) fix jit error for register private serializers --- .../fury/builder/BaseObjectCodecBuilder.java | 29 ++++++++++------- .../src/test/java/io/fury/FuryTest.java | 32 +++++++++++++++++++ 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/builder/BaseObjectCodecBuilder.java b/java/fury-core/src/main/java/io/fury/builder/BaseObjectCodecBuilder.java index 6513103961..9bcd43161b 100644 --- a/java/fury-core/src/main/java/io/fury/builder/BaseObjectCodecBuilder.java +++ b/java/fury-core/src/main/java/io/fury/builder/BaseObjectCodecBuilder.java @@ -481,18 +481,25 @@ protected Expression getOrCreateSerializer(Class cls) { beanClass.getClassLoader() == null ? Thread.currentThread().getContextClassLoader() : beanClass.getClassLoader(); - try { - beanClassClassLoader.loadClass(serializerClass.getName()); - } catch (ClassNotFoundException e) { - // If `cls` is loaded in another class different from `beanClassClassLoader`, - // then serializerClass is loaded in another class different from `beanClassClassLoader`. - serializerClass = LazyInitBeanSerializer.class; - } - if (serializerClass == LazyInitBeanSerializer.class - || serializerClass == ObjectSerializer.class - || serializerClass == CompatibleSerializer.class) { - // field init may get jit serializer, which will cause cast exception if not use base type. + if (!ReflectionUtils.isPublic(serializerClass)) { + // TODO(chaokunyang) add jdk17+ unexported class check. + // non-public class can't be accessed in generated class. serializerClass = Serializer.class; + } else { + try { + beanClassClassLoader.loadClass(serializerClass.getName()); + } catch (ClassNotFoundException e) { + // If `cls` is loaded in another class different from `beanClassClassLoader`, + // then serializerClass is loaded in another class different from `beanClassClassLoader`. + serializerClass = LazyInitBeanSerializer.class; + } + if (serializerClass == LazyInitBeanSerializer.class + || serializerClass == ObjectSerializer.class + || serializerClass == CompatibleSerializer.class) { + // field init may get jit serializer, which will cause cast exception if not use base + // type. + serializerClass = Serializer.class; + } } TypeToken serializerTypeToken = TypeToken.of(serializerClass); Expression fieldTypeExpr = getClassExpr(cls); diff --git a/java/fury-core/src/test/java/io/fury/FuryTest.java b/java/fury-core/src/test/java/io/fury/FuryTest.java index bcbd90bc72..60c1343ef0 100644 --- a/java/fury-core/src/test/java/io/fury/FuryTest.java +++ b/java/fury-core/src/test/java/io/fury/FuryTest.java @@ -62,6 +62,7 @@ import java.util.StringTokenizer; import java.util.TreeMap; import java.util.TreeSet; +import java.util.UUID; import java.util.WeakHashMap; import lombok.AllArgsConstructor; import lombok.Data; @@ -535,4 +536,35 @@ public void testJavaOutputStream() throws IOException { assertEquals(newObj, beanA); } } + + @Data + static class DomainObject { + UUID id; + } + + static class UUIDSerializer extends Serializer { + public UUIDSerializer(Fury fury) { + super(fury, UUID.class); + } + + @Override + public UUID read(MemoryBuffer buffer) { + return new UUID(buffer.readLong(), buffer.readLong()); + } + + @Override + public void write(MemoryBuffer buffer, UUID value) { + buffer.writeLong(value.getMostSignificantBits()); + buffer.writeLong(value.getLeastSignificantBits()); + } + } + + @Test + public void testRegisterPrivateSerializer() { + Fury fury = Fury.builder().withRefTracking(true).requireClassRegistration(false).build(); + fury.registerSerializer(UUID.class, new UUIDSerializer(fury)); + DomainObject obj = new DomainObject(); + obj.id = UUID.randomUUID(); + serDeCheckSerializer(fury, obj, "Codec"); + } }