java
java copied to clipboard
Encode error after reloading a class
In my application I need to reload classes after some changes and I am using jsoniter library to serialize and deserialize the instances of these classes.
I am using a new URLClassLoader to load the classes before instance them and the latest version of classes are picked up.
I got a ClassNotFoundException exception when I was trying to use the JsonStream.serialize method. To solve this problem I try to set the current thread classloader and system classloader to my URLClassLoader before the serialize call and after I put the parent classloader back.
For example using this code:
try {
Thread.currentThread().setContextClassLoader(classLoader);
Field scl = ClassLoader.class.getDeclaredField("scl"); // Get system class loader
scl.setAccessible(true); // Set accessible
scl.set(null, classLoader);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e2) {
e2.printStackTrace();
}
String objectString = null;
try {
objectString = JsonStream.serialize(jsoniterCfg, object);
} catch (Exception e) {
LOGGER.error("Could not serialize the device object. Got this exception",e);
}
try {
Thread.currentThread().setContextClassLoader(classLoader.getParent());
Field scl = ClassLoader.class.getDeclaredField("scl"); // Get system class loader
scl.setAccessible(true); // Set accessible
scl.set(null, classLoader.getParent());
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
Using this code the JsonStream.serialize method manages to found the class and it is working fine when it loads the first time the class but I got these errors when the class is reloaded:
- Encoding: REFLETION_MODE
Config jsoniterCfg = new Config.Builder()
.encodingMode(EncodingMode.REFLECTION_MODE)
.indentionStep(0)
.build();
Exception error:
com.jsoniter.spi.JsonException: java.lang.IllegalArgumentException: object is not an instance of declaring class
at com.jsoniter.output.ReflectionObjectEncoder.encode(ReflectionObjectEncoder.java:41)
at com.jsoniter.output.JsonStream.writeVal(JsonStream.java:381)
at com.jsoniter.output.JsonStream.serialize(JsonStream.java:490)
at com.jsoniter.output.JsonStream.serialize(JsonStream.java:463)
at com.cleverdist.isrd.devicehandler.DeviceProxy.processDeviceRequest(DeviceProxy.java:411)
at com.cleverdist.isrd.devicehandler.DeviceHandler.lambda$init$0(DeviceHandler.java:226)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.jsoniter.output.ReflectionObjectEncoder.enocde_(ReflectionObjectEncoder.java:77)
at com.jsoniter.output.ReflectionObjectEncoder.encode(ReflectionObjectEncoder.java:37)
... 6 common frames omitted
- Encoding: DYNAMIC_MODE
Config jsoniterCfg = new Config.Builder()
.encodingMode(EncodingMode.DYNAMIC_MODE)
.indentionStep(0)
.build();
Exception error:
java.lang.ClassCastException: TESTTYPES cannot be cast to TESTTYPES
at jsoniter_codegen.cfg9223372036682115124.encoder.TESTTYPES.encode(TESTTYPES.java)
at com.jsoniter.output.JsonStream.writeVal(JsonStream.java:381)
at com.jsoniter.output.JsonStream.serialize(JsonStream.java:490)
at com.jsoniter.output.JsonStream.serialize(JsonStream.java:463)
at com.cleverdist.isrd.devicehandler.DeviceProxy.processDeviceRequest(DeviceProxy.java:411)
at com.cleverdist.isrd.devicehandler.DeviceHandler.lambda$init$0(DeviceHandler.java:226)
at java.lang.Thread.run(Thread.java:748)
Could you please tell me how I can use the Jsoniter library for a class that is reloaded?
Thank you for your help.