При удаленном закрытии RMI-сервера возникают проблемы. В моей программе клиент должен подключиться к серверу промежуточного программного обеспечения RMI, а промежуточное программное обеспечение RMI подключается к 3 различным серверам RMI (flightManager, carManager и roomManager). Клиент может отправить команду выключения промежуточному программному обеспечению. Затем промежуточное программное обеспечение должно отключить 3 сервера и сам. Но после того, как я выключил carManager, промежуточное программное обеспечение немедленно выключилось и оставило в живых 2 других сервера.
Промежуточное программное обеспечение соединяет 3 менеджера и получает заглушки от 3 менеджеров. При получении вызова на отключение выполняет следующую функцию:
public void shutdown() throws RemoteException{
try{
this.carManager.shutdown();
this.flightManager.shutdown();
this.roomManager.shutdown();
UnicastRemoteObject.unexportObject(this, true);
System.out.println("Server exiting.");
}
catch(Exception e){}
System.exit(0);
}
Это код для 3 разных менеджеров, он расширяет ResourceManger и дает промежуточному программному обеспечению заглушку как IResourceManager.
public class RMIResourceManager extends ResourceManager
{
private static String s_serverName = "Server";
private static String s_rmiPrefix = "test";
public static void main(String args[])
{
if (args.length > 0)
{
s_serverName = args[0];
}
// Create the RMI server entry
try {
// Create a new Server object
RMIResourceManager server = new RMIResourceManager(s_serverName);
// Dynamically generate the stub (client proxy)
IResourceManager resourceManager = (IResourceManager)UnicastRemoteObject.exportObject(server, 0);
// Bind the remote object's stub in the registry
Registry l_registry;
try {
l_registry = LocateRegistry.createRegistry(1099);
} catch (RemoteException e) {
l_registry = LocateRegistry.getRegistry(1099);
}
final Registry registry = l_registry;
registry.rebind(s_rmiPrefix + s_serverName, resourceManager);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
registry.unbind(s_rmiPrefix + s_serverName);
System.out.println("'" + s_serverName + "' resource manager unbound");
}
catch(Exception e) {
System.err.println((char)27 + "[31;1mServer exception: " + (char)27 + "[0mUncaught exception");
e.printStackTrace();
}
}
});
System.out.println("'" + s_serverName + "' resource manager server ready and bound to '" + s_rmiPrefix + s_serverName + "'");
}
catch (Exception e) {
System.err.println((char)27 + "[31;1mServer exception: " + (char)27 + "[0mUncaught exception");
e.printStackTrace();
System.exit(1);
}
// Create and install a security manager
if (System.getSecurityManager() == null)
{
System.setSecurityManager(new SecurityManager());
}
}
public RMIResourceManager(String name)
{
super(name);
}
}
И, наконец, класс ResourceManager реализует IResourceManager. В нем есть функция отключения.
public class ResourceManager implements IResourceManager{
public void shutdown() throws RemoteException{
System.exit(1);
}
}
Кажется, любое завершение менеджера вызовет завершение промежуточного программного обеспечения. Функция выключения в промежуточном программном обеспечении исключает строку «this.carManager.shutdown ();» и никогда не оправдывай строки выше. Как я могу справиться с этой проблемой?
На рисунках показана проблема: клиент вводит «выключение». Затем carManager выключается, и промежуточное программное обеспечение немедленно выключается. FlightManager и roomManager остаются в живых.