In this program there is a single remote server which performs miscellaneous work. Because there is only one server, it seems like a singleton pattern could fit well. The problem that a distributed program introduces is that every client will have its own version of a `static` variable. Therefore I have defined a basic `ComputeInterface` which is implemented by two classes. `ComputeServer` is the object which performs the work asked for by clients. `ComputeService` is a class which performs an RMI lookup to the `ComputeServer` and acts like singleton server in the client program. The location information for the Server is maintained in a `Configuration` class: public class Configuration { public static final int COMPUTE_REMOTE_PORT = 8900; public static final String COMPUTE_REMOTE_ID = "COMPUTE_REMOTE_ID"; public static final String COMPUTE_REMOTE_HOST = "localhost"; } A `ComputeTask` implements `Serializable` and is performed by the `ComputeInterface` which implements `Remote`. The `ComputeInterface` contains an `isConnected` method which is used for determining if there is connectivity to the server from the service: public interface ComputeTask extends Serializable{ void doWork(); } public interface ComputeInterface extends Remote { ComputeTask compute(ComputeTask task) throws RemoteException; boolean isConnected() throws RemoteException; } This is the implementation for the server: final class ComputeServer extends UnicastRemoteObject implements ComputeInterface { public static void main(String[] args) throws RemoteException, AlreadyBoundException { ComputeServer computeServer = new ComputeServer(); Registry registry = LocateRegistry.createRegistry(Configuration.COMPUTE_REMOTE_PORT); registry.bind(Configuration.COMPUTE_REMOTE_ID, computeServer); System.out.println("Compute Server Running"); } private ComputeServer() throws RemoteException { super(); } @Override public synchronized ComputeTask compute(ComputeTask task) throws RemoteException{ task.doWork(); return task; } @Override public synchronized boolean isConnected() throws RemoteException{ return true; } } And here is the `Service`. If the server has not yet been connected, the service will attempt to do a registry lookup on the server. If the registry lookup up was successful *(or has already been performed)*, it will check the server connectivity before performing any tasks. final public class ComputeService implements ComputeInterface{ public static final ComputeInterface service = new ComputeService(); private static ComputeInterface computeServer; private ComputeService(){} @Override public synchronized boolean isConnected() throws RemoteException{ return ComputeService.connected(); } private static boolean connected(){ if (computeServer == null) { try{ Registry reg = LocateRegistry.getRegistry(Configuration.COMPUTE_REMOTE_HOST, Configuration.COMPUTE_REMOTE_PORT); computeServer = (ComputeInterface) reg.lookup(Configuration.COMPUTE_REMOTE_ID); System.out.println("New Connection to Compute Server"); } catch (RemoteException | NotBoundException e){ System.err.print(e); computeServer = null; return false; } } try{ return computeServer.isConnected(); } catch (RemoteException e){ System.err.print(e); computeServer = null; } return false; } @Override public synchronized ComputeTask compute(ComputeTask task) throws RemoteException{ if(!ComputeService.connected()) return task; return computeServer.compute(task); } } The use of this tool would then simply be: CustomComputeTask task = new CustomComputeTask(); task = ComputeService.service.compute(task);