The RMI server will not thread and die using the LocateRegistry.createRegistry method

Now I use LocateRegistry.createRegistry(1099) instead of using the registry in an external process. However, the registry dies after the completion of the main program. For example, if I create a simple program that creates a registry, this will not work, because after the main executable code, the code ends. I was expecting the LocateRegistry code LocateRegistry create the stream, but it seems like it is not. Is this normal behavior when using LocateRegistry or am I missing something?

Code example:

 // ommited imports public class RMITest { public static void main(String[] args) { LocateRegistry.createRegistry(1099); // JVM will exit now!!! } } 

The RMI server starts and dies suddenly. how

+4
source share
3 answers

I was expecting LocateRegistry code to create a thread

It's not so easy.

  • Exporting the first object to a new port creates a thread that listens on this port, and not exporting the last object listening on the port causes this thread to exit. This applies to all remote objects, and not just to local registry objects.

  • Unexporting can happen automatically through a local GC, which in turn can be started by a remote DGC.

Your JVM exits because you do not store the value returned by LocateRegistry.createRegistry() in a static variable, so it gets GC'd, so the object becomes unexcited, so remote objects are not exported to port 1099, so it listens for 1099 outputs, therefore there are no non-daemon threads, so the JVM shuts down.

Solution: save the result of LocateRegistry.createRegistry() in a static variable. You can use this to not export the registry when you want your JVM to shut down.

+8
source

There are two possible ways to start the RMI registry.

  • LocateRegistry.createRegistry(1099); The java application running the registry should not terminate. In your case, you can start a new "endless" thread (see below for source code).
  • rmiregistry This is a tool included with the java distribution that starts the RMI registry service. see rmiregistry - registry of deleted Java objects

Sample code for the RMI registry server.

 import java.io.IOException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; public class RmiTest { public static void main(String[] args) throws IOException { final Object monitor = new Object(); new Thread(new Runnable() { public void run() { try { LocateRegistry.createRegistry(1099); synchronized (monitor) { monitor.wait(); } } catch (RemoteException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("RMI Registry Thread finished."); } }, "RMI Registry Thread").start(); System.out.println("Press enter to exit..."); System.in.read(); synchronized (monitor) { monitor.notify(); } } } 
+4
source
 LocateRegistry.createRegistry(1099); 

creates a new daemon thread named RMI TCP Accept-1099 on my machine. This topic essentially listens to new TCP / IP connections on 1099.

Daemon threads are automatically destroyed when exiting the JVM. And in your case, the JVM exits when you leave the main() method. More precisely - it exits when there are no non-demon threads - and, apparently, in your application there is only one thread without a daemon (named main ).

So, you have two options:

  • Do not let the main() method complete by adding infinite sleep() .
  • create a non-daemon stream. Of course, do this only when the thread is really doing something useful, rather than preventing the JVM from exiting.
0
source

Source: https://habr.com/ru/post/1380068/


All Articles