Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
Description
For each thin client cache operation marshaling/unmarshaling of objects performed twice. For example, cache "put" operation marshal object on the client-side, then unmarshal object (with keep binaries) on the server-side and marshal it again before putting it to the cache. It causes some undesirable effects. For example, references to the same binary object in a collection ( new ArrayList(Arrays.asList(person, person)) ) deserialized as different objects.
Reproducer:
try (IgniteClient client = startClient()) { ClientCache<Integer, Object[]> cache = client.getOrCreateCache(DEFAULT_CACHE_NAME); Person person = new Person(0, "name"); cache.put(0, new Object[] {person, person} ); Object[] res = cache.get(0); assertTrue(res[0] == res[1]); }
Also, we need to unwrap binaries recursively since all objects inside collections, arrays and maps become binary objects after marshaling/unmarshalling (see IGNITE-12468)
Also, we don't know do we really need to deserialize binary objects. If object was originally binary there is no evidence of this after marshaling/unmarshaling on server-side. This leads to problems when a binary object was created for unknown class.
Reproducer:
cache.put(0, client.binary().builder("TestType").setField("test", "val").build()); cache.get(0);
Will throw exception:
class org.apache.ignite.binary.BinaryInvalidTypeException: TestType at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:762) at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1757) at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1716) at org.apache.ignite.internal.binary.GridBinaryMarshaller.deserialize(GridBinaryMarshaller.java:319) at org.apache.ignite.internal.client.thin.ClientBinaryMarshaller.deserialize(ClientBinaryMarshaller.java:74) at org.apache.ignite.internal.client.thin.ClientUtils.unwrapBinary(ClientUtils.java:558) at org.apache.ignite.internal.client.thin.ClientUtils.readObject(ClientUtils.java:547)
To avoid double marshaling we could pass byte array from request content to cache directly (for example using CacheObject), but we don't have object size in thin client protocol, so in any case, we need to traverse the objects. Also, we don't have the ability to get CacheObject from the cache now, so such an approach will only work in one way, for "put" operations, but not for "get" operations.
Attachments
Issue Links
- is related to
-
IGNITE-12468 ClassCastException on thinClient in Apache Ignite
- Resolved
-
IGNITE-12543 When put List<List<SomeObject>>, the data was increased much larger.
- Resolved
- relates to
-
IGNITE-20688 Java Thin Client - Error while deserializing Collection
- Resolved
- links to