На самом деле просто отмена регистрации и немедленный вызов System.exit не завершаются корректно. Это в основном разрывает соединение, прежде чем сообщить клиенту, что сообщение было завершено. Что работает, так это запустить небольшую ветку, которая закрывает систему, например:
public void quit() throws RemoteException {
System.out.println("quit");
Registry registry = LocateRegistry.getRegistry();
try {
registry.unbind(_SERVICENAME);
UnicastRemoteObject.unexportObject(this, false);
} catch (NotBoundException e) {
throw new RemoteException("Could not unregister service, quiting anyway", e);
}
new Thread() {
@Override
public void run() {
System.out.print("Shutting down...");
try {
sleep(2000);
} catch (InterruptedException e) {
// I don't care
}
System.out.println("done");
System.exit(0);
}
}.start();
}
Поток необходим для того, чтобы что-то происходило в будущем, при этом возвращаясь из метода quit.