Due to the limitation on the client JVM, I can not use any of the popular serializers due to the fact that reflection is not supported. I am looking for a tool that perform byte-code manipulation to achieve serialization by injecting writer and reader methods into the already compiled class. I need byte-code manipulation java code to bind it with my code for building process.
I have been doing this by generating code and injecting it into the source code before compiling to use my custom serializer. I would like to avoid this approach as I don't want yo modify the source files in any way.
I am aware of Kryo and other XML and JSON serializers, but they don't match my needs.
Thanks.
Java serialization uses reflection to scrape all necessary data from the object's fields, including private and final fields. If a field contains an object, that object is serialized recursively. Even though you might have getters and setters, these functions are not used when serializing an object in Java.
Similar to the Flex side, serializing complex objects can be faciliated using class AttributeBasedSerializer . This serializer uses reflection to serialize objects of different class types.
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
Serialization with records With Java Serialization, a record class is made serializable just like a normal class, simply by implementing java. io.
Try javassist. It's probably the most straightforward bytecode generation library for your particular project.
That's because you'll be able to reuse part of your current code generator as javassist is able to parse some simple forms of java code.
For instance you can do:
CtClass clazz = ...;
CtMethod m = CtNewMethod.make(
"public void serialize(java.io.DataOutput out) { out.writeInt(x); }",
clazz);
If you want to dive deep into bytecode generation you can try asm. Asm will allow you to write bytecode directly but it seems to be an overkill for you type of problem.
Implementation with javassist
Here is the base skeleton to do this with javassist:
Path inputDir = Paths.get("target/classes");
Path outputDir = Paths.get("target/classes2");
ClassPool classPool = new ClassPool(true);
classPool.appendClassPath(inputDir.toString());
// get all class names from a certain directory
String[] classNames = Files.walk(inputDir)
.filter(p -> (!Files.isDirectory(p)) && p.toString().endsWith(".class"))
.map(p -> inputDir.relativize(p).toString())
.map(s -> s.substring(0, s.length() - 6).replace(File.separatorChar, '.'))
.toArray(size -> new String[size]);
for (String className : classNames) {
CtClass clazz = classPool.get(className);
// add further filtering to select the classes you want.
// ex: "public void serializer(java.io.DataOutput out) { out.writeInt(x); } }"
String serializerBody = generateSerializer(clazz);
clazz.addMethod(CtNewMethod.make(serializerBody, clazz));
// ex: "public void deserializer(java.io.DataInput in) { x = in.readInt(); } }";
String deserializerBody = generateDeserializer(clazz);
clazz.addMethod(CtNewMethod.make(deserializerBody, clazz));
// save the modified class
clazz.setModifiers(clazz.getModifiers() & ~Modifier.ABSTRACT);
byte[] bytes = clazz.toBytecode();
Path outFile = outputDir.resolve(className.replace('.', '/') + ".class");
Files.createDirectories(outFile.getParent());
Files.write(outFile, bytes);
}
Dependency: org.javassist:javassist:3.19.0-GA
You can use my library Byte Buddy for this purpose. Byte Buddy is a byte code manipulation library and it allows you to easily add methods to any existing class. Furthermore, it allows you inject redefined code into a jar file. This way, you could ask Byte Buddy to redefine classes to add the required methods. However, note that adding methods to a class might change its implicit serialization uuid.
If your classes must not be loaded until your application starts up, Byte Buddy allows you to redefine classes without loading them. For this, you can use Byte Buddys type pool.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With