java icon indicating copy to clipboard operation
java copied to clipboard

Encode error after reloading a class

Open apetrucci opened this issue 7 years ago • 0 comments

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:

  1. 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
  1. 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.

apetrucci avatar Aug 24 '18 07:08 apetrucci