Search code examples
javaservicermikryokryonet

Kryonet RMI throw exception => loop (StackOverflowError)


We using Kryonet to call server methods via RMI. If the service returns a normal value (like true/false) it is working fine.

But when the service throws an Exception, we get an endless loop resulting in a StackOverflowError on the Server.

Exception in thread "Server" java.lang.StackOverflowError
at com.esotericsoftware.kryo.Kryo.getRegistration(Kryo.java:472)
at com.esotericsoftware.kryo.util.DefaultClassResolver.writeClass(DefaultClassResolver.java:97)
at com.esotericsoftware.kryo.Kryo.writeClass(Kryo.java:517)
at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:76)
at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:518)
at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:552)
at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:80)
at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:518)
at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:552)
at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:80)
at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:518)

Service:

public class AuthServiceImpl extends BaseServiceImpl implements AuthService {

public boolean checkLogin(String username, String password) throws Exception {
    // ...
    throw new Exception("Test");
}

}

Call on client:

Boolean state = null;
try {
    state = service.checkLogin("Test", "password");
} catch (Exception e) {
    // Login Faild
    // ...
}
return state;

All Classes are registered in kryo.

  • Service
  • Exceptions
  • Types

Can't Kryonet handle exceptions over RMI?


Solution

  • You have probably an exception with a cause which reference itself.

    If you can't handle this cause, you should enable references when initializing KryoSerialization.

    Kryo kryo = new Kryo();
    kryo.setReferences(true);
    KryoSerialization serialization = new KryoSerialization(kryo);
    
    Server server = new Server(16384, 2048, serialization);