javacallbackrmifunctional-interface

Make a callback with JAVA RMI


I am currently implementing a kind of bag of tasks using Java RMI. The goal is for a "Client" to submit "Task" objects to a "Server," and on the other hand, I have "Workers" that pick up tasks to execute them.

However, I would like to implement a callback so that the Workers can send a result back to the clients (if it needs to go through the server, that's possible too). I'm not sure how to achieve this, though. I should mention that the tasks performed by the workers can take several hours, so I would like the result to reach the client at the end.

I tried to add a TaksCallBack object, which is a FunctionalInterface, to my "Task" object sent to the server and pass anonymous functions, but it tells me that these are not serializable.

I'm not necessarily looking to proceed like this; I'm looking for a way to do it. I'm not very familiar with JAVA, and I'm required to do it with JAVA RMI.

For now, I'm just trying to understand how everything works, so my Task object is relatively simple:

public Task(int taskId, String query, TaskCallback callback) {
    this.taskId = taskId;
    this.query = query;
    this.callback = callback;
}

Solution

  • Solution : You have to share a interface like this :

    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    public interface CallbackInterface extends Remote {
    
        void handler(String string) throws RemoteException;
    }
    

    Sender have to use a class like :

    import java.rmi.RemoteException;
    import java.rmi.server.UnicastRemoteObject;
    
    @FunctionalInterface
    interface LambdaFunction {
        void handler(String string);
    }
    
    public class Callback extends UnicastRemoteObject implements CallbackInterface {
        LambdaFunction function;
    
        public Callback(LambdaFunction function) throws RemoteException {
            this.function = function;
        }
    
        public void handler(String result) {
            this.function.handler(result);
        }
    }
    

    And you can use it with :

    // Sender : 
    server.submitTask(task, new Callback(Client::method));
    // Receiver : 
    callback.handler(...);