Skip to main content
Version: 0.15

Troubleshooting

This page covers common issues and their solutions.

Class Inconsistency and Class Version Check​

If you create Fory without setting CompatibleMode to org.apache.fory.config.CompatibleMode.COMPATIBLE, and you get a strange serialization error, it may be caused by class inconsistency between the serialization peer and deserialization peer.

In such cases, you can invoke ForyBuilder#withClassVersionCheck to create Fory to validate it. If deserialization throws org.apache.fory.exception.ClassNotCompatibleException, it shows classes are inconsistent, and you should create Fory with ForyBuilder#withCompatibleMode(CompatibleMode.COMPATIBLE).

// Enable class version check to diagnose issues
Fory fory = Fory.builder()
.withLanguage(Language.JAVA)
.withClassVersionCheck(true)
.build();

// If ClassNotCompatibleException is thrown, use compatible mode
Fory fory = Fory.builder()
.withLanguage(Language.JAVA)
.withCompatibleMode(CompatibleMode.COMPATIBLE)
.build();

Note: CompatibleMode.COMPATIBLE has more performance and space cost. Do not set it by default if your classes are always consistent between serialization and deserialization.

Using Wrong API for Deserialization​

Make sure you use the matching API pairs:

Serialization APIDeserialization API
Fory#serializeFory#deserialize
Fory#serializeJavaObjectFory#deserializeJavaObject
Fory#serializeJavaObjectAndClassFory#deserializeJavaObjectAndClass

Wrong usage examples:

// ❌ Wrong: serialize with serialize, deserialize with deserializeJavaObject
byte[] bytes = fory.serialize(object);
Object result = fory.deserializeJavaObject(bytes, MyClass.class); // Wrong!

// ❌ Wrong: serialize with serializeJavaObject, deserialize with deserialize
byte[] bytes = fory.serializeJavaObject(object);
Object result = fory.deserialize(bytes); // Wrong!

Correct usage:

// ✅ Correct: matching API pairs
byte[] bytes = fory.serialize(object);
Object result = fory.deserialize(bytes);

byte[] bytes = fory.serializeJavaObject(object);
MyClass result = fory.deserializeJavaObject(bytes, MyClass.class);

byte[] bytes = fory.serializeJavaObjectAndClass(object);
Object result = fory.deserializeJavaObjectAndClass(bytes);

Deserialize POJO into Another Type​

If you want to serialize one POJO and deserialize it into a different POJO type, you must use CompatibleMode.COMPATIBLE:

public class DeserializeIntoType {
static class Struct1 {
int f1;
String f2;

public Struct1(int f1, String f2) {
this.f1 = f1;
this.f2 = f2;
}
}

static class Struct2 {
int f1;
String f2;
double f3;
}

static ThreadSafeFory fory = Fory.builder()
.withCompatibleMode(CompatibleMode.COMPATIBLE).buildThreadSafeFory();

public static void main(String[] args) {
Struct1 struct1 = new Struct1(10, "abc");
byte[] data = fory.serializeJavaObject(struct1);
Struct2 struct2 = (Struct2) fory.deserializeJavaObject(data, Struct2.class);
}
}

Common Error Messages​

"Class not registered"​

Cause: Class registration is required but the class wasn't registered.

Solution: Register the class before serialization:

fory.register(MyClass.class);
// or with explicit ID
fory.register(MyClass.class, 100);

"ClassNotCompatibleException"​

Cause: Class schema differs between serialization and deserialization.

Solution: Use compatible mode:

Fory fory = Fory.builder()
.withCompatibleMode(CompatibleMode.COMPATIBLE)
.build();

"Max depth exceeded"​

Cause: Object graph is too deep, possibly indicating a circular reference attack.

Solution: Increase max depth if legitimate, or check for malicious data:

Fory fory = Fory.builder()
.withMaxDepth(100) // Increase from default 50
.build();

"Serializer not found"​

Cause: No serializer registered for the type.

Solution: Register a custom serializer:

fory.registerSerializer(MyClass.class, new MyClassSerializer(fory));

Performance Issues​

Slow Initial Serialization​

Cause: JIT compilation happening on first serialization.

Solution: Enable async compilation:

Fory fory = Fory.builder()
.withAsyncCompilation(true)
.build();

High Memory Usage​

Cause: Large object graphs or reference tracking overhead.

Solutions:

  • Disable reference tracking if not needed: .withRefTracking(false)
  • Use custom memory allocator for pooling
  • Consider row format for large datasets

Large Serialized Size​

Cause: Metadata overhead or uncompressed data.

Solutions:

  • Enable compression: .withIntCompressed(true), .withLongCompressed(true)
  • Use compatible mode only when needed
  • Register classes to avoid class name serialization

Debugging Tips​

  1. Enable class version check to diagnose schema issues
  2. Check API pairing - ensure serialize/deserialize APIs match
  3. Verify registration order - must be consistent across peers
  4. Enable logging to see internal operations:
LoggerFactory.setLogLevel(LogLevel.DEBUG_LEVEL);