[ 
https://issues.apache.org/jira/browse/IGNITE-13563?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Pavel Tupitsyn updated IGNITE-13563:
------------------------------------
    Fix Version/s: 2.10

> Deserializing IBinaryObject containing an IBinaryObject field fails
> -------------------------------------------------------------------
>
>                 Key: IGNITE-13563
>                 URL: https://issues.apache.org/jira/browse/IGNITE-13563
>             Project: Ignite
>          Issue Type: Bug
>          Components: binary, platforms
>    Affects Versions: 2.8.1
>         Environment: Arch Linux (updated Oct 5): Linux 5.8.12, DotNet 
> 3.1.108, OpenJDK 1.8.0_265.
>            Reporter: Bojidar Marinov
>            Assignee: Bojidar Marinov
>            Priority: Major
>             Fix For: 2.10
>
>         Attachments: 0001-Fix-IBinaryObject-Deserialize.patch, Program.cs
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> When one has a data object which has an IBinaryObject property, like so:
> {code:c#}
> class Model {
>     public IBinaryObject Value { get; set; }
> }
> {code}
> .. and proceeds to fill that property with an IBinaryObject of an unknown 
> type (e.g. a binary object from a cache that has WithKeepBinary on):
> {code:c#}
> var binary = ignite.GetBinary();
> var model = new Model { Value = binary.GetBuilder("nonexistent").Build() };
> {code}
> Then, the resulting object is savable/loadable from caches, as expected:
> {code:c#}
> var cache = ignite.GetOrCreateCache<string, Model>("models");
> cache.Put("model", model);
> var modelFromCache = cache.Get("model"); // Equivalent to model
> {code}
> However, trying to convert the object to IBinaryObject (using ToBinary) and 
> then deserializing that manually fails:
> {code:c#}
> var binaryObject = binary.ToBinary<IBinaryObject>(model);
> var modelFromBinary = binaryObject.Deserialize<Model>(); // Unknown pair 
> [platformId=1, typeId=486454369]
> {code}
> I have attached a program which reproduces the issue.
> ----
> After investigating the issue, it seems to occur because 
> {{BinaryObject.Deserialize<T>()}} uses {{BinaryMode.Deserialize}}. This, in 
> turn, causes {{BinaryReader.ReadBinaryObject()}} to call 
> {{BinaryReader.Deserialize()}} for the first {{BinaryTypeId.Binary}} object 
> found (while switching to {{BinaryMode.KeepBinary}} for nested objects). 
> Then, {{BinaryReader.ReadFullObject()}} gets called, and not knowing better, 
> tries to deserialize the object of a nonexistent type.
> Now, {{BinaryMode.Deserialize}} is also used by {{CacheClient}}. However, 
> upon further investigation of the values passed to {{Marshaller.Unmarshall}}, 
> {{CacheClient}} unmarshalls values starting with {{BinaryTypeId.Binary}}, 
> while {{BinaryObject}} unmarshalls values starting directly with 
> {{BinaryUtils.HdrFull}}; thus, {{BinaryReader}} functions correctly for 
> caches but fails with binary objects.
> Due to the this, I think the proper fix would be to change 
> {{BinaryObject.Deserialize<T>()}} to use {{BinaryMode.KeepBinary}}. I have 
> attached a patch file containing that fix and an accompanying test.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to