Why is java compiler throwing "Unreachable catch block for RemoteException." in a try-catch where there is a RemoteException?

I have this code:

public static void main(String[] args) {

         
        try {
            
            Registry registro = LocateRegistry.getRegistry();
            
            EchoInt stub = (EchoInt) UnicastRemoteObject.exportObject(new EchoObjectRMI(), 0);
            // bind (or rebind) the stub into the local registry
            registro.rebind("echoRemote", stub);
        } catch (RemoteException e) {
            System.err.println("Something wrong happended on the remote end");
            e.printStackTrace();
            System.exit(-1); // can't just return, rmi threads may not exit
        }
        System.out.println("The echo server is ready");
    }
}

But when i try to run it the compiler throws this error:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    Unreachable catch block for RemoteException. This exception is never thrown from the try statement body

    at server.EchoObjectRMI.main(EchoObjectRMI.java:33)

I don’t understand why. In theory, the exportObject method thows the RemoteException exception so, why is saying “This exception is never thrown from the try statement body”?

The error you’re seeing, “Unreachable catch block for RemoteException,” likely occurs because the LocateRegistry.getRegistry() method does not throw a RemoteException, which can make the compiler interpret that the RemoteException is not actually being thrown in your try block.

To address this, try restructuring your code to isolate the methods that actually throw a RemoteException, specifically UnicastRemoteObject.exportObject. You can do this by nesting your try-catch or by simply refactoring the code slightly to make it clearer to the compiler.

Here’s how you can rewrite it:

public static void main(String[] args) {
    try {
        // Connect to or create the RMI registry
        Registry registro = LocateRegistry.getRegistry();

        // Export the EchoObjectRMI instance and bind it to the registry
        EchoInt stub = (EchoInt) UnicastRemoteObject.exportObject(new EchoObjectRMI(), 0);
        
        // bind (or rebind) the stub into the local registry
        registro.rebind("echoRemote", stub);

        System.out.println("The echo server is ready");
        
    } catch (RemoteException e) {
        System.err.println("Something wrong happened on the remote end");
        e.printStackTrace();
        System.exit(-1); // can't just return, RMI threads may not exit
    }
}

Explanation

In this version:

  • UnicastRemoteObject.exportObject is the only method call that can throw a RemoteException directly. This method exports the EchoObjectRMI object and handles any RMI-related exceptions.
  • LocateRegistry.getRegistry() doesn’t throw RemoteException; instead, it only connects to the existing registry or returns an interface without an exception.

If you’re running into this error despite isolating exportObject, double-check the EchoObjectRMI and EchoInt class definitions. Ensure that:

  1. EchoObjectRMI correctly implements EchoInt.
  2. Both classes are imported and compiled correctly.