10

I have the following RMI server code:

public class ServerProgram {
    public ServerProgram() {
        try {
            LocateRegistry.createRegistry(1097);
            Calculator c = new CalculatorImpl();
            String name = "rmi://host:port/name";
            Naming.rebind(name, c);
            System.out.println("Service is bound......");
        } catch (Exception e) {
        }
    }
    public static void main(String[] args) {
        new ServerProgram();
    }
}

When the above program running, it keeps running to wait for client requests. But what I do not understand is what make that program keeps running while it is not in something like while(true){}; and how to stop it from listening, except stopping the whole program?

ipkiss
  • 13,311
  • 33
  • 88
  • 123

3 Answers3

6

What makes it keep running is a non-daemon listening thread started by RMI. To make it exit, unbind the name and unexport both the Registry and the remote object, with UnicastRemoteObject.unexportObject().

user207421
  • 305,947
  • 44
  • 307
  • 483
  • 1
    @Muhammad Wrong answers get downvoted, that's how SO works, and downvotes should be explained (a) as a courtesy to their author (b) for the benefit of others and (c) for the purpose of discussion. This is called 'peer review'. – user207421 Sep 16 '11 at 22:06
1

To stop it, you should call

LocateRegistry.getRegistry().unbind("rmi://host:port/name");
datalost
  • 3,765
  • 1
  • 25
  • 32
  • Wrong. Unbinding is not sufficient to stop it unless several other conditions are met. – user207421 Sep 16 '11 at 21:26
  • @EJP What are those conditions? – Usman Saleem Sep 16 '11 at 22:04
  • 2
    All the remote objects would have to be unexported. That in turn can be accomplished either directly, as per my answer, or via the operation of DGC and local GC, if there are no remote or local live references to the remote objects. – user207421 Sep 16 '11 at 22:12
-2

But what I do not understand is what make that program keeps running while it is not in something like while(true){}; and how to stop it from listening, except stopping the whole program?

This is done by a edit non-editdaemon thread. See: What is Daemon thread in Java? You can test the behavior with this little example:

public class DaemonThread extends Thread
{
  public void run(){
    System.out.println("Entering run method");
    try
    {
      System.out.println(Thread.currentThread());
      while (true)
      {
        try {Thread.sleep(500);}
        catch (InterruptedException x) {}
        System.out.println("Woke up");
      }
    }
    finally { System.out.println("run finished");}
  }

  public static void main(String[] args) throws InterruptedException{
    System.out.println("Main");
    DaemonThread t = new DaemonThread();
    t.setDaemon(false);  // Set to true for testing
    t.start();
    Thread.sleep(2000);
    System.out.println("Finished");
  }
}

The setting prevents the JVM to shut down. after System.out.println("Finished"); you still see the thread running with it's "Woke up" log outputs.

Community
  • 1
  • 1
Thor
  • 6,607
  • 13
  • 62
  • 96
  • Not an answer. Daemon threads *don't* stop the JVM from exiting: that's the whole point. Doesn't answer the question at all. – user207421 Sep 16 '11 at 21:29
  • 4
    Non-daemon threads prevent the JVM from exiting. See [Java Language Specification](http://download.oracle.com/javase/7/specs/jls/JLS-JavaSE7.pdf) – Adrian Pronk Sep 16 '11 at 21:38