LouisLou2 opened a new issue, #2077:
URL: https://github.com/apache/fury/issues/2077

   ### Question
   
   **Environment**:
   - Fury version: 0.10.0
   - Mode: XLANG
   - Language: Java
   - Peer Language: Go
   
   **Description**:
   In Fury 0.10.0, when using XLANG mode, an issue occurs during 
deserialization when a Fury instance registers more than one class, and the 
peer language is not Java. Specifically, the error happens when attempting to 
deserialize a `SomeClass3` object serialized by Fury in Go. The error message 
thrown by FuryJava is as follows:
   
   ```
   Exception in thread "main" 
org.apache.fury.exception.ClassNotCompatibleException: Hash 528 is not 
consistent with 16369 for class null
        at 
org.apache.fury.serializer.StructSerializer.xread(StructSerializer.java:173)
        at org.apache.fury.Fury.xreadNonRef(Fury.java:1046)
        at org.apache.fury.Fury.xreadRef(Fury.java:982)
        at org.apache.fury.Fury.xdeserializeInternal(Fury.java:854)
        at org.apache.fury.Fury.deserialize(Fury.java:792)
        at org.apache.fury.Fury.deserialize(Fury.java:718)
        at org.apache.fury.Main.main(Main.java:225)
   ```
   
   However, when only registering `SomeClass3`, the deserialization works 
correctly without any issues.
   
   ### Steps to Reproduce:
   1. Register both classes in FuryGo:
      ```go
      fury.register(SomeClass3.class, "SomeClass3");
      fury.register(SomeClass2.class, "SomeClass2");
      ```
   2. Serialize an instance of `SomeClass3` using FuryGo.
   3. Attempt to deserialize the serialized data in FuryJava.
   4. Observe the error mentioned above.
   
   ### Analysis:
   Upon investigation, I found the following code snippet in 
`ClassResolver::addSerializer(Class<?> type, Serializer<?> serializer)`:
   
   ```java
   short typeId = serializer.getXtypeId();
   if (typeId != Fury.NOT_SUPPORT_CROSS_LANGUAGE) {
       if (typeId > Fury.NOT_SUPPORT_CROSS_LANGUAGE) {
           typeIdToClassXLangMap.put(typeId, type);
       }
       if (typeId == Fury.FURY_TYPE_TAG_ID) {
           typeTag = serializer.getCrossLanguageTypeTag();
           typeTagToClassXLangMap.put(typeTag, type);
       }
   }
   ```
   
   For custom classes like `SomeClass3` and `SomeClass2`, the `serializer` is 
always a `StructSerializer`. However, the `getXtypeId()` function in 
`StructSerializer` always returns `Fury.FURY_TYPE_TAG_ID`, as seen below:
   
   ```java
   @Override
   public short getXtypeId() {
       return Fury.FURY_TYPE_TAG_ID;
   }
   ```
   
   This causes the mapping in `typeIdToClassXLangMap.put(typeId, type)` to be 
overwritten each time, since both classes use the same `typeId`. As a result, 
during deserialization, the following line in `Fury::xreadNonRef(MemoryBuffer 
buffer, Serializer<?> serializer)` retrieves the last mapping for 
`Fury.FURY_TYPE_TAG_ID`, which leads to an incorrect class being returned (in 
my case, it was `SomeClass2` instead of `SomeClass3`):
   
   ```java
   cls = classResolver.getClassByTypeId((short) -typeId);
   ```
   
   ### Question:
   This behavior seems to suggest that a single Fury instance in XLANG mode can 
only handle one custom class. Is this behavior by design, or is this a bug?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to