LocateRegistry.createRegistry() doesn't keep application alive

1.1k Views Asked by At

I've rubberduck debugged every line of code along with multiple working examples but for some reason my java application just closes when I start an RMI server.

I expect the java application to keep running because I have started a Registry and I have rebound an object that implements java.rmi.Remote.

But what happens is that the application stops right after it's created everything.

Here's my Main.java:

package com.distribridge.servercomponent;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {

    private static Logger logger = Logger.getLogger(Main.class.getName());
    private static int portNumber = 1099;

    private Main() {
        logger.log(Level.INFO, "Starting component");

        Server server;
        try {

            server = new Server();
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Could not create server.");
            System.exit(1);
            return;
        }

        logger.log(Level.FINE, "Server created.");

        Registry registry;
        try {
            registry = LocateRegistry.createRegistry(portNumber);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Could not create registry");
            System.exit(1);
            return;
        }

        logger.log(Level.FINE, "Registry created.");

        try {
            registry.rebind("server", server);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Could not bind server.");
            System.exit(1);
            return;
        }

        logger.log(Level.FINE, "Server bound.");
        logger.log(Level.INFO, "Component started.");
    }

    public static void main(String[] args) {
        System.out.println("Start");
        Main main = new Main();
    }
}

And my Server.java looks like this:

public class Server implements IServerForClientLogin, IServerForClient, IServerForTable, Remote {
    Server() {
        System.out.println("Server Constructor");
    }

    //Some methods that don't get called yet.
}

The interfaces the server extends are in a "Shared" module. I started the project with that module and added modules like the server.

Here's what my console output is:

Start 
Jan 03, 2018 1:10:05 PM com.distribridge.servercomponent.Main <init>
INFO: Starting component
Server Constructor 
Jan 03, 2018 1:10:05 PM com.distribridge.servercomponent.Main <init>
INFO: Component started.

Process finished with exit code 0

As you can see, the process just closes immediately while the registry has a remote object bound.

1

There are 1 best solutions below

3
On BEST ANSWER

The Registry that you store the result of LocateRegistry.createRegistry() into needs to be static.

Otherwise it can be garbage-collected, which unexports it, which allows all the stubs in it to be GC'd, which allows the remote objects they refer to to be DGC'd, which unexports them, which allows the RMI accept threads to exit, which allows the JVM to exit.

However you have another problem. Your Server isn't a remote object yet. You need to export it, either by extending UnicastRemoteObject or calling UnicastRemoteObject.exportObject() on it. At present it is just a mobile agent that is carted bodily to the client and executes there.

Server doesn't need to implement Remote directly. It needs to implement interfaces that extend Remote.