Motivation:
To aid in remote debugging (Java), it's useful to be able to request remote servers to send over arbitrary objects to my local machine for inspection. However, this means that the remote server must be able to serialize an arbitrary java object that is not known in advance at runtime.
So I asked around and stumbled on the Kryo serialization library. From Kryo's documentation, a major feature is that it's very robust at serializing arbitrary java objects. Objects don't have to implement Serializable
, don't need no-arg constructors to be deserializable and I don't even need to know anything about the structure of the object prior to serialization. Perfect!
Problem:
So to test Kryo out, I tried to see if I could serialize and then deserialize a PrintWriter
object (i.e. an arbitrary object):
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import java.io.*;
public class SerializationTest {
private static final String ioFileName = "someIO.bin";
public static void main(String[] args) {
// Create a PrintWriter object that I will later attempt to serialize
PrintWriter outObj = null;
try {
outObj = new PrintWriter("textfile.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Change the PrintWriter's state as a test for later to see if state is restored after serialization and deserialization
outObj.println("Hello"); // "Hello" held in PrintWriter's buffer
Kryo kryo = new Kryo(); // Initialize Kryo serialization
writeObj(kryo, outObj); // Save PrintWriter object to file with "Hello" still in its buffer
// Read the previously saved Printwriter object (still with "Hello" in its buffer)
PrintWriter inObj = (PrintWriter) readObj(kryo);
inObj.close(); // commit "Hello" to disk (using deserialized object)
outObj.close(); // commit "Hello" to disk (using original object)
System.out.println(inObj);
}
public static Object readObj(Kryo kryo) {
Object obj = null;
try {
Input input = new Input(new FileInputStream(ioFileName));
obj = kryo.readClassAndObject(input); // ERROR HERE!!
input.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return obj;
}
public static void writeObj(Kryo kryo, Object obj) {
try {
Output output = new Output(new FileOutputStream(ioFileName));
kryo.writeClassAndObject(output, obj);
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Serialization works fine, but upon deserialization the call to kryo.readClassAndObject(input)
on line 39 gives the following IllegalAccessError
:
Exception in thread "main" java.lang.IllegalAccessError: tried to access class sun.nio.cs.UTF_8 from class sun.nio.cs.UTF_8ConstructorAccess
at sun.nio.cs.UTF_8ConstructorAccess.newInstance(Unknown Source)
at com.esotericsoftware.kryo.Kryo$DefaultInstantiatorStrategy$1.newInstance(Kryo.java:1234)
at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1086)
at com.esotericsoftware.kryo.serializers.FieldSerializer.create(FieldSerializer.java:547)
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:523)
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:704)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:106)
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:704)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:106)
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:704)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:106)
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:704)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:106)
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:786)
at SerializationTest.readObj(SerializationTest.java:39)
at SerializationTest.main(SerializationTest.java:27)
I had hoped that I could serialize and deserialize the PrintWriter
object outObj
, and the object's state would remain in tact so I could still use the deserialized object to write "Hello"
which would have been held in buffer.
Does anyone know what's going on and how to rectify this error?