In short, I was having trouble getting multiple non-daemon Java-RMI threads to close after my application no longer needs RMI. This prevents the JVM from exiting when main () completes.
I understand that exporting UnicastRemoteObject will cause RMI to leave threads open until you get a call to UnicastRemoteObject.unexportObject(Object o,boolean force) . Here's an example (starting without modification and the JVM will exit fine - delete the call to unexportObject and the JVM will never exit):
import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; public class TestUnicastRemoteObject{ private static UnicastRemoteObject obj; private static Registry registry; public static void main(String[] args) throws Exception{ obj = new UnicastRemoteObject(){ private static final long serialVersionUID = 1L; }; System.err.println("created UnicastRemoteObject"); System.err.println("creating registry ..."); registry = LocateRegistry.createRegistry(9999); System.err.println("registry created."); System.err.println("binding obj to registry ..."); registry.bind("Test", obj); System.err.println("bound"); UnicastRemoteObject.unexportObject(obj, true); System.err.println("unexported obj"); } }
Also, it doesn't matter if you create a registry and / or bind a remote object to it - the only thing that seems to matter in this example is that every time you create a UnicastRemoteObject, you need to call unexportObject to prevent the remaining flows after completion.
In my application, I made sure that I called the unexportObject file for each UnicastRemoteObject created, but nonetheless, the RMI reaper stream and connection accept stream are still saved, which prevents my JVM from exiting when my application terminates using RMI resources.
Is there anything else that could make RMI leave threads except forgetting the UnicastRemoteObjects exception?
Codeblind
source share