[MW] Aufgabe 4


Wie genau holst du das Teil dann wieder aus der Registry? Bei mir sieht das dann so aus:

public class LibraryFrontend extends
java.rmi.server.UnicastRemoteObject implements DBObserver, java.io.Serializable {
	
	private SimpleDB database;
	public LibraryFrontend(String location) throws MalformedURLException, RemoteException, NotBoundException {
			this.database = (SimpleDB) Naming.lookup(location);
	}
...

Die Interfaces, die dein LibraryFrontend implementiert sind aus der 2. Teilaufgabe, oder? Das steht bei mir noch nicht da.

Ansonsten hab ich aktuell das hier da stehen:

			Object o = Naming.lookup("rmi://localhost/mwlibrary");
			db = (SimpleDBImpl) o;

Ja, muss ich noch in SimpleDB ändern seh ich grad. Nun hab ich einen Breakpoint gesetzt, um mir o anzuschauen, nachdem es gesetzt wurde. Der Debugger zeigt mir dann an, dass “o” vom Typ “$Proxy0” ist. Als nächstes gibt’s ne Cast-Exception, ist ja klar.


Ich hab gerade das tolle Problem, dass unsere RMI-Library auf OS X ohne Probleme läuft und ich deswegen abgeben wollte…sogar inklusive Startskripte und lauter so Kram, alles hat gepasst :slight_smile:

Dann kopier ichs per tar+scp in den cip, wills vor der Abgabe nur zum Spaß nochmal ausführen, und dann krachts fürchterlich:

java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: 
        java.io.EOFException
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:203)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:350)
        at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
        at java.rmi.Naming.rebind(Naming.java:160)
        at sichdamm.mwlibrary.server.RMIServer.main(RMIServer.java:20)
Caused by: java.io.EOFException
        at java.io.DataInputStream.readByte(DataInputStream.java:333)
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:189)
        ... 4 more
RMIServer fertig. SimpleDB bereit!
./startserver: line 3:  3277 Segmentation fault      rmiregistry 27326

Das mit Abstand beste find ich ja dann den Segfault von rmiregistry :wand:

Wo is denn da das Problem?? Ich hab schon die Stubs/Skeletons mit rmic neu generiert(könnte ja irgendwas nicht zusammenpassen, rmic im CIP is nämlich vom gcj, nix von Sun), aber das hilft auch nix.
Liegts eventuell daran, dass rmic im CIP vom gcj kommt?

Wir könnten natürlich auch mit dem Hinweis abgeben, dass es auf OS X läuft… g


Hast du jetzt den Cast auf (SimpleDB) dastehen? Falls das immer noch eine Exception gibt, dann hast du ein falsches Objekt registriert oder ein richtiges Objekt falsch registriert :].


Hm, es bleibt ein $Proxy0, das scheint aber nicht weiter zu stören, da es sich offensichtlich in ein SimpleDB casten lässt. Kommt Eclipse bloß nicht damit klar oder ist das normal? Naja, bin jetzt schonmal weiter und hab somit erstmal wieder was zu tun… :slight_smile:


Das kann so doch garnicht funktionieren. Du musst doch noch den Port angeben und außerdem hast du ja quasi das Interface exportiert (weil dich auf dem Client die Implementierung überhaupt nicht interiesiert, sondern nur der Aufruf), also musst du dir auch nur das Interface holen:

			Object o = Naming.lookup("rmi://localhost:12345/mwlibrary");
			db = (SimpleDB) o;

Den Cast hab ich ja noch geändert, hab ich ja schon geschrieben. Aber mein Problem trat ja eh vor dieser Zeile auf. Und den Port kann ich mir sparen, wenn ich die rmiregistry ohne Portangabe gestartet hab. K.A. auf welchem Port das dann läuft, könnt mit netstat nachschauen, aber Server und Client werden wohl schon die selben Vorgabewerte haben. :wink: (Und da ich auf meinem Computer der einzige Nutzer bin, geht das glaub ich i.O…)


Wie habt ihr denn den DBObserver gemacht? Ich hab mich glaub ich an die Übungsfolien gehalten und LibraryFrontend implements DBObserver gemacht, das libraryfrontend dann als Observer auf dem RMIServer hinzugefügt und in der newItem-Methode einfach ne Textausgabe gemacht. Leider passiert da irgendwie nix sinnvolles. Der Client bekommt von einem register nichts mit und auf dem Server erscheint eine Reihe von ######### in der Ausgabe. Der Observer wird benachrichtigt, das hab ich mir schon rausprotokollieren lassen, danach kommen nur diese ###. Ist das etwa die verkrüppelte Ausgabe, die eigentlich auf dem Client erscheinen sollte? Wo kommt das her umd warum wird newItem niemals auf dem Client aufgerufen (per Debugger geprüft)? Exceptions treten keine auf und die restliche Funktionalität der Bibliothek geht ohne Probleme. Bei 2 Clients erscheinen die #### eben zweimal.


wie registrierst du denn die Clients beim Server?


LibraryFrontend..ctor():
    db = Naming.lookup(url);
    db.addObserver(this);

LibraryFrontend.newItem(key):   // Callback-Funktion
    System.out.println(... + key);

SimpleDBImpl.addObserver(DBObserver obs):
    observers.add(obs);   // <-- Vector<DBObserver>

SimpleDBImpl.register(key, ...):
    for (DBObserver obs : observers)
        obs.newItem(key);

Also an sich sieht das schon gut aus. Die ganzen Stubs / Skel für das Remote Objekt erzeugst du? Irgendwelche Interfaces vergessen anzugeben? Ansonsten kann ich mit deiner Fehlermeldung nicht viel anfangen.


Ups, muss man da noch irgendwas erzeugen? Außer SimplDB halt.


Naja, der Client wird ja auch Remote ausgeführt


Ja, du musst aber nicht die Stubs und Skeletons für die Interfaces erzeugen sondern für ihre Implementierung. Das wären in deinem Fall SimpleDBImpl und LibraryFrontend.


Muss ich dann LibraryFrontend auch per rmiregistry veröffentlichen? Dann haut aber das Konzept auf den Folien nicht mehr hin.


Nope, nur die DB


Hab jetzt rmic über LibraryFrontend laufen lassen, keine Fehlermeldungen. Alles wieder gestartet, aber keine Veränderung. Immer noch ### aufm Server und nix im Client. Muss ich am Code noch was ändern?


Hat sich erledigt. Der Meik hat mir empfohlen, das LibraryFrontend nicht serialisierbar zu machen, wodurch es komplett zum Server übertragen wird, sondern es stattdessen von UnicastRemoteObject abzuleiten. Jetzt geht’s. :slight_smile: