В моем приложении мне нужно перезагрузить классы после некоторых изменений, и я использую библиотеку jsoniter для сериализации и десериализации экземпляров этих классов.
Я использую новый URLClassLoader для загрузки классов до того, как они будут созданы, и будет выбрана последняя версия классов.
Я получил исключение ClassNotFoundException, когда пытался использовать метод JsonStream.serialize
. Чтобы решить эту проблему, я попытался установить текущий загрузчик классов потока и системный загрузчик классов на свой URLClassLoader до вызова сериализации и после того, как я вернул родительский загрузчик классов обратно.
Например, используя этот код:
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();
}
Используя этот код, метод JsonStream.serialize
удается найти класс, и он работает нормально, когда загружает класс в первый раз, но я получаю эти ошибки при перезагрузке класса:
- Кодировка: REFLETION_MODE
Config jsoniterCfg = new Config.Builder ()
.encodingMode (EncodingMode.REFLECTION_MODE)
.indentionStep (0)
.build ();
Ошибка исключения:
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
Config jsoniterCfg = new Config.Builder ()
.encodingMode (EncodingMode.DYNAMIC_MODE)
.indentionStep (0)
.build ();
Исключительная ошибка:
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)
Не могли бы вы рассказать, как я могу использовать библиотеку Jsoniter для перезагружаемого класса?
Спасибо за вашу помощь.