motaa
motaa

Reputation: 337

RMI; JRMP connection error; Caused by connection reset

I get the following Exception and I can't figure out why that is happening.

java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: java.net.SocketException: Connection reset
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.newCall(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at Daemon$ShutDownProcedure.run(Daemon.java:126)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readByte(Unknown Source)
... 5 more

I have a Daemon class that is responsible to start up a Server in a separate JVM. In that Daemon I have a ShutDownHook that calls a method on the remote server object which, on the server, starts a shutdown procedure.

The Daemon itself is also an exported RMI object but on a different port so that I can start a server remotely. That means the Daemon has created a Registry listening on port 1099 and the Server has a Registry listening on post 1098.

Now I also have a "ClientGui" that can shutdown a server and restart it. It can access both the Daemon to launch a server and the Server to shut it down.

Daemon class:

//.....
private Daemon(String[] args){
    try {
        this.reg = LocateRegistry.createRegistry(1099);
        this.stub = (DaemonRemote) UnicastRemoteObject.exportObject(this, 1099);
        this.reg.rebind(DaemonRemote.class.getName(), this.stub);   
        this.arguments = args;
        Runtime.getRuntime().addShutdownHook(new ShutDownProcedure());          
    } catch (RemoteException e) {
        e.printStackTrace();
    }       
}

//....
public static void main(String[] args){             

  String initialargs = Arrays.stream(args).collect(Collectors.joining(" "));
  String[] command = new String[] {"java", "-Xmx4g","-cp", System.getProperty("java.class.path", "."), Server.class.getName(),initialargs};

  try {
    p = new ProcessBuilder(command).inheritIO().redirectErrorStream(true).start();          
    } catch (Exception e) {
      e.printStackTrace();  
    }       
    if(daemon == null)
        daemon = new Daemon(args);
}
//....
private class ShutDownProcedure extends Thread {

    @Override
    public void run(){      

        if(p.isAlive()){
          try {
            Registry serverreg = LocateRegistry.getRegistry(null, 1098);
            ServerRemote serverrmi = (ServerRemote) serverreg.lookup(ServerRemote.class.getName()); //this is the line where the exception occurs...
            serverrmi.killServer();
          } catch (IOException | NotBoundException | InterruptedException e) {          
            e.printStackTrace();
        }
    }
}

}

From my ClientGui I access the remote Server object in exactly the same way as from the Daemon and can also call the killServer() method without a problem. But when I hit CTRL+C to initiate the ShutDownHook from the Daemon, the mentioned exception is being thrown when trying to lookup the exported Server object.

The websearch didn't give me any ideas on how to solve this... but maybe I am looking in the wrong direction...

Any help is greatly appreciated and I thank anyone in advance! :)

Upvotes: 1

Views: 7684

Answers (2)

motaa
motaa

Reputation: 337

As already stated in the comments, hitting "CTRL+C" during the batch-job (the Daemon is being started from cmd executing a bat-file) shuts down both JVM's and thus the registry created in the server JVM shuts down as well.

To resolve my issue I just added a ShutDownHook to the server which will initiate its own ShutDownProcedure. Unfortunately I haven't found a good way to start a completely separate "unhidden" cmd-window and start another jar-application using ProcessBuilder yet.

Thanks to EJP's advice, I removed the Registry creation part from the code and start it from the batch-file.

Upvotes: 0

user207421
user207421

Reputation: 310840

This is all pointless. You're shutting down the entire JVM. That will take the Registry you created in your JVM with it, along with all the bindings. In fact obviously the Registry has already exited during your lookup() call.

Just remove your shutdown hook.

In any case if you are the remote object yourself, you don't need to lookup the Registry to find yourself. All you needed was to unbind and then unexport yourself. But you don't even need that.

Upvotes: 1

Related Questions