Search code examples
javarmijobs

Java RMI server run as daemon, client connection refused


If I run run my Java RMI server as a daemon (with & at the end), seems it always automatically stopped

This is the command to start the RMI server

java -Djava.security.policy=java.policy -cp .:lib/mysql-connector-java-5.1.7-   bin.jar:lib/jsch-0.1.44.jar com.company.remote.server.rmi.RemoteServiceRmi &

Here is the printout:

user@agent033:~/remoteconfig> java -Djava.security.policy=java.policy -cp .:lib/mysql-connector-java-5.1.7-bin.jar:lib/jsch-0.1.44.jar com.company.remote.server.rmi.RemoteServiceRmi &
[3] 7437
Remote Object bind at (RMI): //10.***.***.***3002/RemoteConfigure
Remote Object: RemoteServiceImpl[UnicastServerRef [liveRef: [endpoint:[10.***.***.***:3003](local),objID:[3412cf8e:147646da428:-7fff, 7055633182216564676]]]]

Here I input a carriage return

[3]+  Stopped                 java -Djava.security.policy=java.policy -cp .:lib/mysql-connector-java-5.1.7-bin.jar:lib/jsch-0.1.44.jar com.company.remote.server.rmi.RemoteServiceRmi

If I don't input the carriage return, the "Stopped" line will not be shown up. The client still cannot talk to server. Client will get:

error during JRMP connection establishment; nested exception is:
java.net.SocketTimeoutException: Read timed out

If I remove the "&" at the end of the command, the server can start successfully and the client can talk to server without any problem.

Here is the code of server side RMI initialization:

private void initializeRmiService() throws RemoteException, MalformedURLException {
    int registryPort = Integer.parseInt(PropertyHandler.getProperty("rmi_regport"));
    String connectionPort = PropertyHandler.getProperty("rmi_connport");
    String rmiNamingUrl = "";

    RemoteServiceInterface agent = new RemoteServiceImpl(Integer.parseInt(connectionPort));
    rmiNamingUrl = "//" + PropertyHandler.getProperty("rmi_hostaddress") + ":" + registryPort + "/" + PropertyHandler.getProperty("rmi_naming");
    logger.info("Remote Object bind at (RMI): " + rmiNamingUrl);
    if (System.getSecurityManager() == null) {
        System.setSecurityManager(new SecurityManager());
    }
    LocateRegistry.createRegistry(registryPort);
    Naming.rebind(rmiNamingUrl, agent);
    logger.info("Remote Object: " + agent);
}

Solution

  • When you run something from a shell and supply a & suffix, this runs it in the background.

    This problem has little to do with RMI and probably has something to do with a backgrounded process attempting to read from the terminal. On most Unix-like systems, if a backgrounded process attempts to read from the terminal (usually, but not always its standard input), the OS will automatically stop the process. The reason is that, since the process is in the background, there is likely some other process that's in the foreground reading from the terminal. If two processes are reading from the terminal at the same time, input to the processes will be interleaved in an unpredictable way, which would be bad.

    See this answer for more information.

    I bet you have code somewhere in your RMI server that is reading from System.in. Take it out, and your process should run well in the background. The problem with RMI is that your process is stopped by the OS, so connection requests time out. If you avoid reading from the terminal, the process won't stop in the background. There should be no issue listening to sockets and accepting RMI connections while running in the background.