I posted this question earlier in this thread, but let me try asking the question again by itself.
How do I get a remote object to die?
In case you're wondering the related question "WHY do I want a remote object to die?", the answer is that the remote object's class is emma-instrumented, and I can't see any of its coverage statistics until it terminates.
Here's what I've got so far. On the server side, I run an app whose main method creates a security manager, creates an RMI registry, calls Naming.rebind to attach a name to the registry, and then falls off the end of the main method. I run this app from the command line, and it never terminates (i.e. gives me another command prompt), even after the client has called a remote method that calls UnicastRemoteObject.unexportObject(this), and even after the client has terminated itself. I can kill it from the command line with an INTR signal, but that doesn't give emma time to save its coverage data, and intuitively there must be a cleaner way.
Failing this, does emma have an API that allows the program to explicitly ask it to save the data so far?
Okay, I did a short example program, and I think that the problem can be solved in two ways.
It all boils down to that second parameter to UnicastRemoteObject.unbind(). (The boolean force.) Here's the JavaDoc for UnicastRemoteObject. Scroll down to the unbind() method near the bottom and be sure to read the comments on force. If force is true then the object is unbound, no matter what. When I did this, the program exited right away.
However, if instead force is false, it only unexports the object if there are no pending or in-progress calls. Unfortunately, if you make this call inside a remote method, the current method call is an in-progress remote call, so the object is not unexported. This can be verified by the return value from unbind() - if you make the call inside a remote method it constantly returns false. If you really want to set force to true, you're going to need to let the remote call end first. Create a separate thread that waits for a short while, and then call unbind() in the new thread context. Have your remote method simply start this thread and then return.
Write once, run anywhere, because there's nowhere to hide! - /. A.C.