javarmikryokryonet

Kryonet. RMI. Response timed out while trying to execute remote method


I`m trying to bootstrap simple kryonet RMI project with two separate client and server applications.

But when I try to execute remove method - it leads to:

Exception in thread "main" com.esotericsoftware.kryonet.rmi.TimeoutException: Response timed out: jemmy.IJemmyCommander.run
at com.esotericsoftware.kryonet.rmi.ObjectSpace$RemoteInvocationHandler.invoke(ObjectSpace.java:408)
at com.sun.proxy.$Proxy0.run(Unknown Source)
at jemmy.dummy.client.RunClient.main(RunClient.java:29)

There is source code: server and client.

How to get it work? It should print "Run" on server console.


Solution

  • You have severals issues in your projects :

    1. You must have a shared datamodel between your client and your server. You can keep server classes privates, but they must implement interfaces known by your client

    When a client invokes a method on a remote object, it will send over the wire an InvokeMethod with the identifier of the remote object and a method. On the server, the object is lookup and the method is invoked. If the interfaces didn't match, you`ll get an "object is not an instance of the declaring class" exception.

    1. You must share the same configuration for your Kryo instance : Your client and your server must register the same classes in the same order

    Kryo has a mapping between classes names and internals ID. If you register explicitly a class, then this class will use an id, in order to minimize traffic. If you register on your server the same class with another id, then client and server will not match the same classes, and the message will fail.

    1. In your server, you should register through an ObjectSpace objects which can be invoked by your client

    ObjectSpace is a registry of remote objects. It's responsible for the creation of proxies, and the handler of InvokeMethod messages. On the server, you should link each connection to one or several ObjectSpace.

    On your project :

    1. Create a third jar containing commons interfaces between your client and your server. This jar can contain also a helper class to create a Kryo instance. More easily, just create a dependency from your server to your client, and register the same classes (only IJemmyCommander is necessary)

    2. Make JemmyCommand implements IJemmyCommand

    3. On your server, add :

      server.addListener(new Listener() {
         @Override
         public void connected(Connection connection) {
            // 44 is the identifier of the JemmyCommander, referenced by a client
            new ObjectSpace(connection).register(44, new JemmyCommander());
         }
      });