RMI Problem beim shutdown von verteilter CORBA-Anwendung

dermorti

Mitglied
Moin moin,

ich habe ein Problem in meiner verteilten CORBA-Anwendung ...
Ich habe drei Projekte, ein Server, ein Monitor und einen Client.

Soweit rennt auch alles, aber ich habe einen Fehler, wenn ich vom Client das quit auf meinem Server aufrufe und der ORB geschlossen wird.

Im Groben rennt das Programm folgendermaßen:

Der Server wird gestartet und meldet ein Objekt am Namensdienst an, danach blockiert der Aufruf
Java:
orb.run()
bis der ORB geschlossen wird mittels
Java:
orb.shutdown(false/true)
.

Anschließend werden ein oder mehrere Monitore gestartet, die sich am Server anmelden und von da an nur Log-Nachrichten auf der Konsole ausgeben.

Der Client kann auf dem Server Methoden aufrufen und allerlei Dinge tun. Unter anderem eben die quit-Methode des Servers aufrufen. Der Server ruft daraufhin auf allen angemeldeten Monitoren die quit-Methode auf und danach erfolgt ein unbind beim NameServer und danach ein shutdown des ORBs.

Bei meiner Lösung gibt es nun immer mal wieder eine CORBA-Exception namens "BAD_INV_ORDER", dabei ist es egal, ob ich
Java:
orb.shutdown(true)
oder
Java:
orb.shutdown(false)
nutze. Bei true kommt es hin und wieder vor, dass der Server dann gar nicht mehr beendet wird und er beim shutdown stehen bleibt. Allerdings funktioniert es auch häufiger, ohne dass eine Exception geworfen wird, ich vermute, dass es mit der Ausführungsgeschwindigkeit/Reihenfolge des Threads (der den orb.shutdown() macht) zusammenhängen könnte.

Versucht habe ich, den shutdown durch einen extra Thread durchzuführen, weil der Anwendung ja sonst die CORBA-Verbindung beim AUfruf entzogen wird.

hier mal die relevanten Code-Ausschnitte:


quit()-Methode des Servers, die vom Client aus aufgerufen wird.
Java:
	public void quit() {
		System.out.println("Server>Client quitted server");
		System.out.print("Server>quitting all monitors...");
		
		removeAllMonitors();
		
		System.out.print("OK\nServer>unbinding...");
		
		try {
			ncRef.unbind(path);
		} catch (NotFound e) {
			e.printStackTrace();
		} catch (CannotProceed e) {
			e.printStackTrace();
		} catch (InvalidName e) {
			e.printStackTrace();
		}
		
		System.out.print("OK\nServer>shutting down ORB...");
		
		orb.shutdown(false);
		
		System.out.println("OK\nServer>shutdown was successful...");
	}

quit()-Methode des Monitors
Java:
	public void quit() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println("Monitor>quit");
				orb.shutdown(false);
			}
		}).start();
	}

removeAllMonitors();
Java:
	public void removeAllMonitors() {
		for (Iterator<Monitor> iterator = lagerMonitore.iterator(); iterator.hasNext();) {
			Monitor moni = iterator.next();
			try {
				moni.quit();
			} catch (Exception e) {
				System.out.println("Monitor.quit() threw: " + e.getMessage());
			} finally {
				iterator.remove();
			}
		}
	}


der Client macht einfach nur einen simplen Aufruf auf den Servant, also der Methode quit() auf dem Server.
Java:
	private void quit() {
		lagerRef.quit();
	}

Ich habe bereits versucht, beim Server ebenfalls das orb.shutdown() in einen eigenen Thread zu legen, wie bei der Monitor quit()-Methode. Mein Problem behebt dies dennoch nicht.

Entweder geht alles glatt ohne Fehler, oder es knallt im Monitor die "BAD_INV_ORDER" Exception oder sie kommt im Server. Beim Client kommt maximal eine CORBA-Comm-Exception.

Wer kann mir bei diesem Problem helfen oder mir einen Hinweis geben, wie ich von meinem Client aus den Server so beenden kann, also das blocken von orb.run() so durch orb.shutdown() beenden, dass dieser alle Monitore beenden kann und dann sich selbst, ohne das ich eine BAD_INV_ORDER Exception bekomme oder der Client eine Corba-Comm-Exception 🙁


PS: Interessant ist noch, dass unter Windows auf der Konsole alles prima läuft, die Fehler sind jetzt beim Testen unter Linux aufgetreten (alles jre1.6) ...
 
Zuletzt bearbeitet:
Moin,

nein einen Thread will ich an der Stelle nicht starten.

orb.run() blockiert nur den laufenden Thread solange, bis orb.shutdown() das Blockieren aufhebt.
Gehört zum ORB Objekt zur Kommunikation mit Namensdienst usw.
 
Soweit rennt auch alles, aber ich habe einen Fehler, wenn ich vom Client das quit auf meinem Server aufrufe und der ORB geschlossen wird.

Selbst wenn alles laufen würde wie Du meint, hinterfrage ich, warum ein Client den Server beenden möchte? Danach gibt es ja keine Möglichkeit mehr den Server wieder zu starten und zumal sich für andere Clients es sich merkwürdig "anfühlt" wenn der Server plötzlich nicht mehr antwortet weil heruntergefahren ob absichtlich oder unabsichtlich.
 
Naja ob das merkwürdig ist oder nicht, ist wohl Geschmackssache, ich finde es hilfreich die Möglichkeit zu haben, einen Server aus der Ferne zu beenden. Gut das mit dem Starten ist so eine Sache ...
In meinem Fall ist dies aber auch egal, es ist eine Übungsaufgabe ...
Der Prof will ein "verteiltes" Lager haben, auf pc a rennt namensdienst und das Lager, auf pc b rennt der Monitor, der alles protokolliert, was mit dem Lager zu tun hat, auf pc c rennt dann der Client. Der wird auch nur mit ein paar Parametern aufgerufen, was er tun soll und beendet sich danach eh wieder, der rennt nicht dauerhaft.
Der Prog möchte nun gerne, dass man aus der Ferne das Lager (Server) beenden kann. Dies geschieht durch den clientseitigen Aufruf der quit() Methode auf dem Lager. In dieser Methode ruft nun ebenfalls das Lager auf allen verbundenen Monitoren ebenfalls deren quit() Methode auf. Anschließend eben shutdown des Orbs.
Und das Ganze soll ohne CORBA Fehler passieren. Probleme kann es eben geben beim orb.shutdown() im Monitor und Server, weil dann natürlich die Kommunikation zwischen Client/Server und ggf. den Monitoren schon weg ist ...
Das ist ja gerade das Problem was ich beheben muss ...
 

Zurück
Oben