[ https://issues.apache.org/jira/browse/IGNITE-16294?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Vladimir Steshin updated IGNITE-16294: -------------------------------------- Description: .NET binary writer doesn't get `System.Enum` field as an enum and uses `WriteObject()->Write()` instead of `WriteEnum()`. Consider: {code:c#} enum TestEnum { Foo, Bar } class TestClass { TestEnum enm = TestEnum.Foo; //Or //Enum enm = TestEnum.Foo; } cache.Put(key, new TestClass()) {code} This code fails with the exception if 'enm' field declared as 'System.Enum'. I see 2 basis of the problem: 1) `System.Enum.IsEnum()` is false whereas certain enum like our 'TestEnum' returns True of course. 2) When e build user-type scheme, we rely on declared type of class field by FieldInfo. But not on real type of the field value. Here we get System.Enum with 'IsEnum==false'. When we serialize user-type object, we check type of the field instance. Here we get certain enum with 'IsEnum==true'. There are several approaches to fix this: 1) Refactor user-type scheme building to check filed value type instead of declared field type. Think doesn't worth `System.Enum`. 2) Fix `BinaryWriter.Write<T>(T obj)` so that it would check if `obj` is `System.Enum` and call `WriteEnum<T>(T val)` 3) Fix `BinarySystemHandlers.FindWriteHandler(Type type)` so that it deal with `SystemEnum`. 4) Fix `TypeCaster<T>.Cast<TFrom>(TFrom obj)` so that it deals with `System.Enum`. #4 looks the most universal to me. {code:c#} InvalidCastException: Specified cast is not valid: System.Enum -> System.Int32] Apache.Ignite.Core.Impl.Common.TypeCaster`1.Cast(TFrom obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Common\TypeCaster.cs:49 Apache.Ignite.Core.Impl.Binary.BinarySystemWriteHandler`1.Write(BinaryWriter writer, T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinarySystemHandlers.cs:650 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1190 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 lambda_method(Closure , Object , IBinaryWriter ) +146 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryUtils.WriteArray(Array val, BinaryWriter ctx, Nullable`1 elemTypeId) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryUtils.cs:1087 Apache.Ignite.Core.Impl.Binary.BinarySystemHandlers.WriteArray(BinaryWriter ctx, Object obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinarySystemHandlers.cs:521 Apache.Ignite.Core.Impl.Binary.BinarySystemWriteHandler`1.Write(BinaryWriter writer, T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinarySystemHandlers.cs:650 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1190 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.SerializableSerializer.WriteEntry(IBinaryWriter writer, SerializationEntry entry) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\SerializableSerializer.cs:553 Apache.Ignite.Core.Impl.Binary.SerializableSerializer.WriteSerializationInfo(IBinaryWriter writer, SerializationInfo serInfo) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\SerializableSerializer.cs:396 Apache.Ignite.Core.Impl.Binary.SerializableSerializer.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\SerializableSerializer.cs:66 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryUtils.WriteArray(Array val, BinaryWriter ctx, Nullable`1 elemTypeId) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryUtils.cs:1087 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteArrayInternal(Array val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1032 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteArray(T[] val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1015 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteArray(String fieldName, T[] val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1005 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryUtils.WriteArray(Array val, BinaryWriter ctx, Nullable`1 elemTypeId) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryUtils.cs:1087 {code} was: .NET binary writer doesn't get `System.Enum` field as an enum and uses WriteObject()->Write() instead of WriteEnum(). Consider: {code:c#} enum TestEnum { Foo, Bar } class TestClass { TestEnum enm = TestEnum.Foo; //Or //Enum enm = TestEnum.Foo; } cache.Put(key, new TestClass()) {code} This code fails with the exception if 'enm' field declared as 'System.Enum'. I see 2 basis of the problem: 1) `System.Enum.IsEnum()` is false whereas certain enum like our 'TestEnum' returns True of course. 2) When e build user-type scheme, we rely on declared type of class field by FieldInfo. But not on real type of the field value. Here we get System.Enum with 'IsEnum==false'. When we serialize user-type object, we check type of the field instance. Here we get certain enum with 'IsEnum==true'. There are several approaches to fix this: 1) Refactor user-type scheme building to check filed value type instead of declared field type. Think doesn't worth `System.Enum`. 2) Fix `BinaryWriter.Write<T>(T obj)` so that it would check if `obj` is `System.Enum` and call `WriteEnum<T>(T val)` 3) Fix `BinarySystemHandlers.FindWriteHandler(Type type)` so that it deal with `SystemEnum`. 4) Fix `TypeCaster<T>.Cast<TFrom>(TFrom obj)` so that it deals with `System.Enum`. #4 looks the most universal to me. {code:c#} InvalidCastException: Specified cast is not valid: System.Enum -> System.Int32] Apache.Ignite.Core.Impl.Common.TypeCaster`1.Cast(TFrom obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Common\TypeCaster.cs:49 Apache.Ignite.Core.Impl.Binary.BinarySystemWriteHandler`1.Write(BinaryWriter writer, T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinarySystemHandlers.cs:650 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1190 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 lambda_method(Closure , Object , IBinaryWriter ) +146 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryUtils.WriteArray(Array val, BinaryWriter ctx, Nullable`1 elemTypeId) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryUtils.cs:1087 Apache.Ignite.Core.Impl.Binary.BinarySystemHandlers.WriteArray(BinaryWriter ctx, Object obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinarySystemHandlers.cs:521 Apache.Ignite.Core.Impl.Binary.BinarySystemWriteHandler`1.Write(BinaryWriter writer, T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinarySystemHandlers.cs:650 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1190 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.SerializableSerializer.WriteEntry(IBinaryWriter writer, SerializationEntry entry) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\SerializableSerializer.cs:553 Apache.Ignite.Core.Impl.Binary.SerializableSerializer.WriteSerializationInfo(IBinaryWriter writer, SerializationInfo serInfo) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\SerializableSerializer.cs:396 Apache.Ignite.Core.Impl.Binary.SerializableSerializer.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\SerializableSerializer.cs:66 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryUtils.WriteArray(Array val, BinaryWriter ctx, Nullable`1 elemTypeId) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryUtils.cs:1087 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteArrayInternal(Array val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1032 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteArray(T[] val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1015 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteArray(String fieldName, T[] val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1005 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, T val) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T obj, BinaryWriter writer) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 Apache.Ignite.Core.Impl.Binary.BinaryUtils.WriteArray(Array val, BinaryWriter ctx, Nullable`1 elemTypeId) in E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryUtils.cs:1087 {code} > .NET serializer fails to convert System.Enum to int. > ---------------------------------------------------- > > Key: IGNITE-16294 > URL: https://issues.apache.org/jira/browse/IGNITE-16294 > Project: Ignite > Issue Type: Bug > Reporter: Vladimir Steshin > Assignee: Vladimir Steshin > Priority: Minor > > .NET binary writer doesn't get `System.Enum` field as an enum and uses > `WriteObject()->Write()` instead of `WriteEnum()`. > Consider: > {code:c#} > enum TestEnum { > Foo, Bar > } > class TestClass { > TestEnum enm = TestEnum.Foo; > > //Or > //Enum enm = TestEnum.Foo; > } > cache.Put(key, new TestClass()) > {code} > This code fails with the exception if 'enm' field declared as 'System.Enum'. > I see 2 basis of the problem: > 1) `System.Enum.IsEnum()` is false whereas certain enum like our 'TestEnum' > returns True of course. > 2) When e build user-type scheme, we rely on declared type of class field by > FieldInfo. But not on real type of the field value. Here we get System.Enum > with 'IsEnum==false'. When we serialize user-type object, we check type of > the field instance. Here we get certain enum with 'IsEnum==true'. > There are several approaches to fix this: > 1) Refactor user-type scheme building to check filed value type instead of > declared field type. Think doesn't worth `System.Enum`. > 2) Fix `BinaryWriter.Write<T>(T obj)` so that it would check if `obj` is > `System.Enum` and call `WriteEnum<T>(T val)` > 3) Fix `BinarySystemHandlers.FindWriteHandler(Type type)` so that it deal > with `SystemEnum`. > 4) Fix `TypeCaster<T>.Cast<TFrom>(TFrom obj)` so that it deals with > `System.Enum`. > #4 looks the most universal to me. > {code:c#} > InvalidCastException: Specified cast is not valid: System.Enum -> > System.Int32] > Apache.Ignite.Core.Impl.Common.TypeCaster`1.Cast(TFrom obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Common\TypeCaster.cs:49 > > Apache.Ignite.Core.Impl.Binary.BinarySystemWriteHandler`1.Write(BinaryWriter > writer, T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinarySystemHandlers.cs:650 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1190 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > lambda_method(Closure , Object , IBinaryWriter ) +146 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryUtils.WriteArray(Array val, > BinaryWriter ctx, Nullable`1 elemTypeId) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryUtils.cs:1087 > > Apache.Ignite.Core.Impl.Binary.BinarySystemHandlers.WriteArray(BinaryWriter > ctx, Object obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinarySystemHandlers.cs:521 > > Apache.Ignite.Core.Impl.Binary.BinarySystemWriteHandler`1.Write(BinaryWriter > writer, T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinarySystemHandlers.cs:650 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1190 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.SerializableSerializer.WriteEntry(IBinaryWriter > writer, SerializationEntry entry) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\SerializableSerializer.cs:553 > > Apache.Ignite.Core.Impl.Binary.SerializableSerializer.WriteSerializationInfo(IBinaryWriter > writer, SerializationInfo serInfo) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\SerializableSerializer.cs:396 > Apache.Ignite.Core.Impl.Binary.SerializableSerializer.WriteBinary(T obj, > BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\SerializableSerializer.cs:66 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryUtils.WriteArray(Array val, > BinaryWriter ctx, Nullable`1 elemTypeId) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryUtils.cs:1087 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteArrayInternal(Array val) > in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1032 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteArray(T[] val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1015 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteArray(String fieldName, > T[] val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1005 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.WriteObject(String fieldName, > T val) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:982 > > Apache.Ignite.Core.Impl.Binary.BinaryReflectiveSerializerInternal.Apache.Ignite.Core.Impl.Binary.IBinarySerializerInternal.WriteBinary(T > obj, BinaryWriter writer) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryReflectiveSerializerInternal.cs:81 > Apache.Ignite.Core.Impl.Binary.BinaryWriter.Write(T obj) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryWriter.cs:1246 > Apache.Ignite.Core.Impl.Binary.BinaryUtils.WriteArray(Array val, > BinaryWriter ctx, Nullable`1 elemTypeId) in > E:\ignite\modules\platforms\dotnet\Apache.Ignite.Core\Impl\Binary\BinaryUtils.cs:1087 > {code} -- This message was sent by Atlassian Jira (v8.20.1#820001)