Возникла проблема с десериализацией классов в WebSphere eXtreme Scale и обратно. Я сначала полагал, что WebSphere eXtreme Scale использует стандартную сериализацию Java, но оказалось, что он по умолчанию использует свой eXtreme Data Format, поэтому может сериализовать даже те классы, которые не помечены как сериализуемые. При этом он, правда, использует стандартную сериализацию Java для тех классов, которые помечены как Serializable или Externalizable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Caused by: com.ibm.websphere.objectgrid.ObjectGridRuntimeException: CWOBJ6339E: The conversion of type [com.google.common.collect.ImmutableMap$SerializedForm] to type [com.google.common.collect.ImmutableMap] failed.~wxs5341 at com.ibm.ws.objectgrid.plugins.io.dataobject.values.ValueDataImpl.getObject(ValueDataImpl.java:336) at com.ibm.ws.objectgrid.DiffMap.get(DiffMap.java:1038) at com.ibm.ws.objectgrid.ObjectMapImpl.get(ObjectMapImpl.java:446) ... 61 more Caused by: com.ibm.websphere.objectgrid.ObjectGridRuntimeException: CWOBJ6339E: The conversion of type [com.google.common.collect.ImmutableMap$SerializedForm] to type [com.google.common.collect.ImmutableMap] failed.~wxs5341 at com.ibm.ws.objectgrid.xdf.JavaFieldAccess.set(JavaFieldAccess.java:50) at com.ibm.ws.objectgrid.xdf.XDFField.setFieldValue(XDFField.java:400) at com.ibm.ws.objectgrid.xdf.serializers.GenericClassSerializer.deserializeFieldToObject(GenericClassSerializer.java:243) at com.ibm.ws.objectgrid.xdf.serializers.GenericClassSerializer.deserializeObject(GenericClassSerializer.java:197) at com.ibm.ws.objectgrid.xdf.serializers.GenericClassSerializer.deserializeFieldToObject(GenericClassSerializer.java:242) at com.ibm.ws.objectgrid.xdf.serializers.GenericClassSerializer.deserializeObject(GenericClassSerializer.java:197) at com.ibm.ws.objectgrid.xdf.XDFSerializerPlugin.inflateDataObject(XDFSerializerPlugin.java:303) at com.ibm.ws.objectgrid.plugins.io.dataobject.values.ValueDataImpl.getObject(ValueDataImpl.java:328) ... 63 more Caused by: java.lang.IllegalArgumentException: Can not set final com.google.common.collect.ImmutableMap field ru.sbrf.ufs.dictionary.model.DictionaryImpl.fields to com.google.common.collect.ImmutableMap$SerializedForm at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) at sun.reflect.UnsafeQualifiedObjectFieldAccessorImpl.set(UnsafeQualifiedObjectFieldAccessorImpl.java:83) at java.lang.reflect.Field.set(Field.java:741) at com.ibm.ws.objectgrid.xdf.JavaFieldAccess.set(JavaFieldAccess.java:42) ... 70 more |
При сериализации и десериализации guava-овских коллекций на Jetty при считывании данных из eXtreme Scale происходит проблема с десериализацией:
Caused by: com.ibm.websphere.objectgrid.ObjectGridRuntimeException: CWOBJ6339E: The conversion of type [com.google.common.collect.ImmutableMap$SerializedForm] to type [com.google.common.collect.ImmutableMap] failed.~wxs5341
коллекции Guava десериализуются в класс
SerializedForm, который по идее не должен покидать пределы внутренностей библиотеки Guava.
Я нашёл следующие статьи:
https://github.com/google/guava/issues/1554
http://stackoverflow.com/questions/9110677/readresolve-not-working-an-instance-of-guavas-serializedform-appears
Проблема, похоже, заключается в разных класслоадерах.
У меня на самом деле проблема была в библиотеке ogclient. У нас в зависимостях jetty-maven-plugin была подключена версия 8.6.0.1, я поменял на 8.6.0.8 и всё заработало.
Вот такая стала зависимость:
1 2 3 4 5 6 7 8 9 10 11 12 |
<!--Клиент eXtremeScale--> <dependency> <groupId>com.ibm.websphere</groupId> <artifactId>ogclient</artifactId> <version>${thirdparty.ogclient.version}</version> </dependency> <!--jar из ibm-jdk без который клиент eXtremeScale не работает--> <dependency> <groupId>com.ibm.jdk</groupId> <artifactId>ibmcfw</artifactId> <version>${thirdparty.ibmcfw.version}</version> </dependency> |
Сам класс ImmutableMap использует стандартную сериализацию через readResolve и writeReplace (подробнее про эти методы в статье про сериализацию в Java)Видимо в старой зависимости подключался какая-та не такая версия guava, в которой не работал readResolve.