Serialization between dotnet core clusternode and framework clusternode does not work properly
NielsHoogeveen opened this issue · 8 comments
When trying to send a Dictionary from a dotnet core 2.1 cluster node to a framework 4.7.2 cluster node, using Hyperion, it fails to deserialize on the receiving side.
It seems the framework 4.7.2. node tries to deserialize the dictionary referencing the assembly "System.Private.CoreLib", which only exists in dotnet core.
The exception reads:
Cause: System.IO.FileNotFoundException: Could not load file or assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
A solution that generates this exception can be found here:
https://github.com/NielsHoogeveen/HyperionTest
The issue is not just related to Dictionary, but I can confirm it also happens with ImmutableDictionary and List.
The issue is more general than I first thought. When a generic type is used and either the generic type itself, or one of its type parameters is defined in mscorlib/System.Private.CoreLib then the deserializer throws an exception on the framework side.
@NielsHoogeveen
Yes problem in this line
Hyperion/src/Hyperion/Extensions/TypeEx.cs
Line 215 in 735c49e
incorrect replacement of the assembly name
I fixed it in my library that uses wire
I confirm I get the same issue, the stack trace:
File name: 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
at System.Type.GetType(String typeName, Boolean throwOnError)
at Hyperion.Extensions.TypeEx.<>c.b__27_0(ByteArrayKey b)
at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func
2 valueFactory)
at Hyperion.Extensions.TypeEx.GetTypeFromManifestName(Stream stream, DeserializerSession session)
at Hyperion.Extensions.TypeEx.GetTypeFromManifestVersion(Stream stream, DeserializerSession session)
at Hyperion.Serializer.GetDeserializerByManifest(Stream stream, DeserializerSession session)
at lambda_method(Closure , Stream , DeserializerSession )
at lambda_method(Closure , Stream , DeserializerSession )
at lambda_method(Closure , Stream , DeserializerSession )
at Hyperion.Serializer.Deserialize[T](Stream stream)
at Akka.Serialization.HyperionSerializer.FromBinary(Byte[] bytes, Type type)
at Akka.Serialization.Serialization.Deserialize(Byte[] bytes, Int32 serializerId, String manifest)
at Akka.Remote.DefaultMessageDispatcher.Dispatch(IInternalActorRef recipient, Address recipientAddress, Payload message, IActorRef senderOption)
at Akka.Remote.EndpointReader.b__11_1(InboundPayload inbound)
at lambda_method(Closure , Object , Action1 , Action
1 , Action1 ) at Akka.Tools.MatchHandler.PartialHandlerArgumentsCapture
4.Handle(T value)
at Akka.Actor.ReceiveActor.ExecutePartialMessageHandler(Object message, PartialAction`1 partialAction)
at Akka.Actor.UntypedActor.Receive(Object message)
at Akka.Actor.ActorBase.AroundReceive(Receive receive, Object message)
at Akka.Actor.ActorCell.ReceiveMessage(Object message)
at Akka.Actor.ActorCell.Invoke(Envelope envelope)
@NielsHoogeveen
Yes problem in this line
Hyperion/src/Hyperion/Extensions/TypeEx.csLine 215 in 735c49e
var part = name.Substring( name.IndexOf(", Version", StringComparison.Ordinal));
incorrect replacement of the assembly name
I fixed it in my library that uses wire
https://github.com/DaniilSokolyuk/SimpleRpc/blob/1a19d34fe2cb9a1379faf4d24ddc15454d9781be/src/SimpleRpc/Serialization/Wire/Library/Extensions/TypeEx.cs#L223
I just tested the same fix. A bunch of unit tests are failing for good reasons, that might not be enough...
Any chance for fix? That breaks DistributedData feature :(
I just came across this problem (while deserializing a System.ValueTuple<string, string>
) and was surprised to see it mentioned in the top issue. I can confirm that @DaniilSokolyuk's solution works (not sure if it breaks anything else though).
I just realized that regrettably, Hyperion doesn't appear to be undergoing much development at the moment, with placeholder documentation, no commits in 2019 and barely nine during the previous year. That's a shame because it seems to perfectly fit my project's requirements.
Does anyone at @akkadotnet have an update? Are there any plans for continued development? Is it worth using the serializer in new projects or putting together pull requests?
closed via #116