Skip to content

Commit

Permalink
Don't need to implement Serializable for json only serialization.
Browse files Browse the repository at this point in the history
  • Loading branch information
avrecko committed Mar 12, 2023
1 parent 3f17042 commit bea5094
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 16 deletions.
7 changes: 5 additions & 2 deletions src/one/nio/serial/GeneratedSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@ public class GeneratedSerializer extends Serializer {
static final AtomicInteger renamedFields = new AtomicInteger();
static final AtomicInteger unsupportedFields = new AtomicInteger();

private final boolean jsonOnlySerialization;

private FieldDescriptor[] fds;
private FieldDescriptor[] defaultFields;
private Delegate delegate;

GeneratedSerializer(Class cls) {
GeneratedSerializer(Class cls, boolean jsonOnlySerialization) {
super(cls);
this.jsonOnlySerialization = jsonOnlySerialization;

Field[] ownFields = getSerializableFields();
this.fds = new FieldDescriptor[ownFields.length / 2];
Expand Down Expand Up @@ -108,7 +111,7 @@ public void skipExternal(ObjectInput in) throws IOException, ClassNotFoundExcept

@Override
public byte[] code() {
return DelegateGenerator.generate(cls, fds, defaultFields);
return DelegateGenerator.generate(cls, fds, defaultFields, jsonOnlySerialization);
}

@Override
Expand Down
9 changes: 4 additions & 5 deletions src/one/nio/serial/Repository.java
Original file line number Diff line number Diff line change
Expand Up @@ -372,14 +372,13 @@ private static Serializer generateFor(Class<?> cls) {
serializer = new CollectionSerializer(cls);
} else if (Map.class.isAssignableFrom(cls) && !hasOptions(cls, FIELD_SERIALIZATION)) {
serializer = new MapSerializer(cls);
} else if (Serializable.class.isAssignableFrom(cls)) {
if (cls.getName().startsWith("java.time.") && JavaInternals.findMethod(cls, "writeReplace") != null) {
} else {
boolean extendsSerializable = Serializable.class.isAssignableFrom(cls);
if (extendsSerializable && cls.getName().startsWith("java.time.") && JavaInternals.findMethod(cls, "writeReplace") != null) {
serializer = new JavaTimeSerializer(cls);
} else {
serializer = new GeneratedSerializer(cls);
serializer = new GeneratedSerializer(cls, !extendsSerializable);
}
} else {
serializer = new InvalidSerializer(cls);
}
serializer.generateUid();
} catch (Throwable e) {
Expand Down
45 changes: 39 additions & 6 deletions src/one/nio/serial/gen/DelegateGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,30 @@ public static Delegate instantiate(Class cls, FieldDescriptor[] fds, byte[] code
}

public static Delegate instantiate(Class cls, FieldDescriptor[] fds, FieldDescriptor[] defaultFields) {
return instantiate(cls, fds, generate(cls, fds, defaultFields));
return instantiate(cls, fds, generate(cls, fds, defaultFields, false));
}

public static byte[] generate(Class cls, FieldDescriptor[] fds, FieldDescriptor[] defaultFields) {
public static byte[] generate(Class cls, FieldDescriptor[] fds, FieldDescriptor[] defaultFields, boolean jsonOnly) {
String className = "sun/reflect/Delegate" + index.getAndIncrement() + '_' + cls.getSimpleName();

ClassWriter cv = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cv.visit(V1_6, ACC_PUBLIC | ACC_FINAL, className, null, MAGIC_CLASS,
new String[]{"one/nio/serial/gen/Delegate"});

generateConstructor(cv, className);
generateCalcSize(cv, cls, fds);
generateWrite(cv, cls, fds);
generateRead(cv, cls, fds, defaultFields, className);
generateSkip(cv, fds);

if (!jsonOnly) {
generateCalcSize(cv, cls, fds);
generateWrite(cv, cls, fds);
generateRead(cv, cls, fds, defaultFields, className);
generateSkip(cv, fds);
} else {
generateThrowCalcSize(cv, cls);
generateThrowWrite(cv, cls);
generateThrowRead(cv, cls);
generateThrowSkip(cv, cls);
}

generateToJson(cv, cls, fds);
generateFromJson(cv, cls, fds, defaultFields, className);

Expand Down Expand Up @@ -362,6 +371,30 @@ private static void generateSkip(ClassVisitor cv, FieldDescriptor[] fds) {
mv.visitEnd();
}

private static void generateThrowNonSerializableMethod(ClassWriter cv, String methodName, String descriptor, Class cls) {
MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_FINAL, methodName, descriptor,
null, new String[]{"java/io/NotSerializableException"});
mv.visitCode();
emitThrow(mv, "java/io/NotSerializableException", cls.getName());
mv.visitEnd();
}

private static void generateThrowCalcSize(ClassWriter cv, Class cls) {
generateThrowNonSerializableMethod(cv, "calcSize", "(Ljava/lang/Object;Lone/nio/serial/CalcSizeStream;)V", cls);
}

private static void generateThrowWrite(ClassWriter cv, Class cls) {
generateThrowNonSerializableMethod(cv, "write", "(Ljava/lang/Object;Lone/nio/serial/DataStream;)V", cls);
}

private static void generateThrowRead(ClassWriter cv, Class cls) {
generateThrowNonSerializableMethod(cv, "read", "(Lone/nio/serial/DataStream;)Ljava/lang/Object;", cls);
}

private static void generateThrowSkip(ClassWriter cv, Class cls) {
generateThrowNonSerializableMethod(cv, "skip", "(Lone/nio/serial/DataStream;)V", cls);
}

private static void generateToJson(ClassVisitor cv, Class cls, FieldDescriptor[] fds) {
MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_FINAL, "toJson", "(Ljava/lang/Object;Ljava/lang/StringBuilder;)V",
null, new String[]{"java/io/IOException"});
Expand Down
5 changes: 2 additions & 3 deletions test/one/nio/serial/JsonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@
import org.junit.Test;

import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;

public class JsonTest implements Serializable {
public class JsonTest {

private long lng = Long.MIN_VALUE;
private Object map = new HashMap<String, String>() {{
Expand Down Expand Up @@ -54,7 +53,7 @@ public void testDateParsing() throws IOException, ClassNotFoundException {
Assert.assertNull(Json.fromJson("{\"date\":\" \"}", TestObject.class).date);
}

public static class TestObject implements Serializable {
public static class TestObject {
@JsonName("test_name")
public String name;
public Date date;
Expand Down

0 comments on commit bea5094

Please sign in to comment.