JAVA Remote Method Invocation RMI/IIOP Tutorial

Werbung
JAVA Remote Method Invocation
RMI/IIOP Tutorial
© Abteilung Technische Informatik, Institut für Informatik, Universität Leipzig
© Abteilung Technische Informatik, Wilhelm Schickard Institut für Informatik
12.6.2013
Version 0.8
Dieses Tutorial stellt die Aufgabe, ein Java-Programm auf einem Client (Ihrem PC) zu
installieren, und mittels RMI einen Zugriff auf einen Java-Server durchzuführen, der in einer
zLinux-LPAR auf unserem z9 Mainframe in Tübingen läuft. Die zLinux-LPAR hat den Namen
galadriel.cs.uni-tuebingen.de (oder 134.2.205.55) .
Danksagung an Herrn Robert Harbach für die Bereitstellung des Materials.
RMI/IIOP
Galadriel
134.2.205.55
Ihr
Arbeitsplatzrechner
Im Gegensatz zu dem JRMP-Tutorial verwenden wir hier RMI/IIOP (gesprochen „RMI over
IIOP“). Wir gehen davon aus, dass Sie vor Bearbeitung dieses Tutorials vorher das JRMPTutorial bearbeitet haben.
Übersicht
1. Das RMI/IIOP Programmiermodell
1.1 Corba
1.2 Java Remote Procedure Call
1.3 Corba und RMI
1.3.1 Naming
1.3.2 rmic
1.3.3 Unterschiede in der Codierung
1.3.4 Unterschiede in der Programm-Ausführung
1.3.5 Literatur
2. RMI/IIOP Programmierung
2.1 Übersicht
2.2 Ihre Aufgabe: Eine verteilte Anwendung mit RMI/IIOP
2.2.1 Szenario
2.2.2 Code Beispiel
2.2.3 Port Nummer
2.2.4 Vorgehen
2.2.4.1 Benötigter Quellcode
2.2.4.2 Das Interface und die Klassen kompilieren
2.2.4.3 Java Kompatibilität
2.2.2.4 Stubs und Skeletons mit rmic erstellen
3. Erstellen der Java-Klassen auf dem zLinux-Server
3.1 Laden der Klassen auf den zLinux-Server
3.2 Zugriff auf zLinux
4. Ausführen des Programms
4.1 Download der Client-Klassen
4.2 Aufruf des Servers
4.3 Herunterfahren des Servers
6. Anhang :Beispielcode
6.1 Konto.java
6.2 KontoImpl.java
6.3 Terminal.java
6.4 security.policy
1. Das RMI/IIOP Programmiermodell
1.1 Corba
Der Corba Remote Procedure Call wurde als Nachfolger für die in den 80er Jahren
dominierenden Sun RPCs und DCE RPCs geplant und entwickelt. Corba Version 1.0 ist seit
1991 verfügbar, Corba 2.0 seit 1992 und Corba 3.0 seit 2002.
Die wichtigsten Eigenschaften von Corba sind:
•
•
•
•
•
•
Die Services eines Corba-Servers werden als Objekte dargestellt und über ObjektKlassen und deren Methodenaufrufe implementiert.
Corba-Klassen (Binaries) können in vielen Sprachen geschrieben werden (z.B. Cobol,
C++, PLI, ADA und Java) und einwandfrei miteinander kommunizieren.
Um dies zu ermöglichen, werden die Schnittstellen der Server-Objekte in einer
einheitlichen Schnittstellensprache, der Corba-IDL (Interface Definition Language)
beschrieben, unabhängig davon, in welcher Programmiersprache das Server-Objekt
geschrieben wurde. Die IDL wird benutzt, um Server-Skeletons und evtl. Client-Stubs zu
erstellen.
Auf dem Client und Server wird je eine einheitliche Laufzeitumgebung benötigt, der
Corba-ORB (Object Request Broker).
Alle Server-Objekte werden über eine eine einheitliche Bezeichnung adressiert, der IOR
(Interoperable Object Reference).
Für die Kommunikation zwischen RMI-Objekten und/oder Corba-Objekten wird das IIOP
(Internet Inter-Orb Protocol) verwendet.
Zusätzlich existieren weitere Corba-Services, z.B. Transaction Service, Naming Service, usw.
IIOP, JRMP, Telnet, 3270, FTP, http und SOAP sind Protokolle der OSI-Layer-Schicht 5 und
verwenden heute fast immer TCP/IP als Schicht-4-Übertragungsprotokoll.
1.2 Java Remote Procedure Call
Bei der Entwicklung der Java-RMI entstand ein mit Corba sehr vergleichbares, aber
inkompatibles Programmiermodell. Spezifisch wurde das proprietäre JRMP-Protokoll und eine
dazu passende Laufzeitumgebung geschaffen. An Stelle der Corba-IDL benutzt man die JavaSchnittstelle, die Bestandteil von Java ist. Der Vorteil dieser Vorgehensweise ist eine etwas
einfachere Programmierung.
Da es Java RMI over JRMP an Interoperabilität mit anderen Sprachen mangelt, wurde
zusätzlich RMI/IIOP geschaffen. Hierzu wurde die JRMP-Laufzeitumgebung durch einen
Corba-ORB, und das JRMP-Protokoll durch das IIOP-Protokoll ersetzt. Damit ist es möglich,
RMI-Objekte in eine Corba-Umgebung einzubinden. RMI-Objekte benutzen das IIOP-Protokoll,
um mit Corba-Objekten zu kommunizieren.
RMI/IIOP bietet den Vorteil, Remote-Interfaces einfach in Java zu schreiben und diese mit den
APIs von Java-RMI zu implementieren. Es ist nicht nötig, eine separate IDL-Sprache zu lernen.
JRMP hat einen Nachteil. Ohne RMI/IIOP sind RMI und Corba zwei getrennte Welten. JRMPClients können nur mit JRMP-Servern, und Corba-Clients nur mit Corba-Servern
kommunizieren.
Die Einführung von RMI/IIOP verbessert diese Situation. Ohne Änderung von existierendem
Code ist es möglich, dass JRMP-Cients mit RMI/IIOP-Server-Objekten kommunizieren, und
umgekehrt. In anderen Worten, JRMP und RMI/IIOP passen nahtlos zusammen. Weiterhin
können Corba-Client-Anwendungen problemlos auf RMI/IIOP-Server-Objekte zugreifen. Beim
Zugriff von RMI/IIOP-Clients auf Corba-Server-Objekte existieren einige Einschränkungen,
wenn es sich um älteren Code handelt.
Der Java-RMI-Standard offeriert heute zwei alternative Protokolle: JRMP und RMI/IIOP.
Manche Softwareunternehmen implementieren beides in ihren RMI-Produkten. IBM hat
entschieden, in ihren Java-Produkten ausschließlich RMI/IIOP einzusetzen.
Man sollte meinen, dass der erhöhte Funktionsumfang von RMI/IIOP gegenüber JRMP eine
schlechtere Performance zur Folge hat. Dies ist interessanterweise nicht unbedingt der Fall.
Die Frage des Unterschieds in der Performance wird im Internet und in den einschlägigen
Foren heiß und kontrovers diskutiert und hängt wohl auch von der konkreten
Anwendungssituation ab. Es scheint aber so zu sein, dass in der Mehrzahl der Fälle RMI/IIOP
in Bezug auf Performance besser abschneidet als JRMP.
Ein ORB (Object Request Broker) ist eine Komponente eines Betriebssystems. Er stellt ein
einheitliches Klassenmodell sowie Standards für die Organisation von Klassen-Bibliotheken
und die Kommunikation zwischen Objekten zur Verfügung. Alle z/OS-Java-Produkte, z.B.
CICS-Java oder der WebSphere-EJB-Container enthalten deshalb einen Corba-ORB.
1.3 Corba und RMI
Es existieren einige Unterschiede in der Programmierung von JRMP- und RMI/IIOPAnwendungen.
1.3.1 Naming
JNDI (Java Naming and Directory Interface) ist eine API, über die ein Java-Programm einen
Namens- und Directory-Dienst in Anspruch nehmen kann. Der Namens- und Directory-Dienst
ermöglicht einen Lookup von RMI-Objekten zwischen entfernten JVMs. Mögliche
Implementierungen der JNDI-Schnittstelle sind z.B. der LDAP-Server, Corba-Common-ObjectServices-Name- (COSNaming-) Server oder der rmiregistry-Server. rmiregistry ist ein
Bestandteil des JDK. JRMP verwendet standardmäßig einen rmiregistry-Server.
RMI/IIOP benutzt statt dessen einen COSNaming-Server, welcher Remote-References als
Interoperable-Object-References (IORs) enthält. Es existieren verschiedene COSNamingServer. Wir verwenden den weit verbreiteten tnameserv, ebenfalls Bestandteil der JDK.
Das Kommando tnameserv –ORBInitialPort startet auf Default-Port 900 (wenn nichts
anderes spezifiziert ist).
RMI erwartet aber einen RMI-Name-Server. Deshalb benötigen wir eine JNDI-nachCOSNaming-Bridge. Die com.sun.jndi.cosnaming.CNCtxFactory-Bridge ist ein
Bestandteil der Sun-JDK, die auf Galadriel installiert ist. Andere Java-Produkte verwenden
eine andere Bridge, WebSphere z.B. verwendet einen eigenen Name-Server und eine eigene
Bridge.
1.3.2 rmic
Der rmic-Compiler erhält die zusätzliche Option –iiop. Damit werden Corba kompatible Stubs
und Skeletons generiert. Weiterhin wird eine Corba-IDL von dem Java-Interface erzeugt.
1.3.3 Unterschiede in der Codierung
Unterschiedliche Import-Statements werden benutzt (vergleichen Sie die Code-Beispiele der
JRMP- und RMI/IIOP-Tutorials).
Das Server-Objekt verwendet anstatt der UnicastRemoteObject- die
PortableRemoteObject-Klasse.
1.3.4 Unterschiede in der Programm-Ausführung
Siehe Teil 4 des Tutorials. Vergleichen Sie es mit dem Teil 4 des JRMP-Tutorials.
1.3.5 Literatur
RMI-IIOP home page
http://java.sun.com/products/rmi-iiop/index.html (obsolet)
RMI-IIOP Programmer's Guide
http://docs.oracle.com/javase/7/docs/technotes/guides/rmi-iiop/rmi_iiop_pg.html
OMG Java language to IDL Mapping specification
ftp://ftp.omg.org/pub/docs/ptc/99-03-09.pdf (obsolet)
http://www.omg.org/spec/JAV2I/
2. RMI/IIOP Programmierung
2.1 Übersicht
Modifizieren Sie ihre bestehende RMI-JRMP-Anwendung so, dass sie das IIOP-Protokoll
benutzt und damit Interoperabilität mit Corba-ORBs bietet. Sichern Sie am besten Ihre alte
RMI/JRMP-Anwendung, bevor Sie sie modifizieren.
RMI/IIOP macht gegenüber dem JRMP-Tutorial die folgende Änderungen notwendig:
•
•
Ihre KontoImpl-Klasse erweitert anstatt der UnicastRemoteObject- die
PortableRemoteObject-Klasse aus dem javax.rmi-Package
Anstatt des rmiregistry-Name-Servers wird diesmal der Corba kompatible COSNamingServer benutzt:
> tnameserv -ORBInitialPort <port>
•
Ihr Server muss in der main-Methode einen Kontext für JNDI erstellen:
import javax.naming.InitialContext;
InitialContext INC = new InitialContext();
Das Binden des Remote-Objekts funktioniert mit der rebind-Methode des InitialContextObjekts und ersetzt die „Registry“ aus der letzten Aufgabe:
INC.rebind("Konto", KontoImpl_object);
•
Erzeugen Sie auf die gleiche Art einen JNDI-Kontext in der main-Methode des Clients.
InitialContext bietet eine entsprechende „lookup“-Methode um eine Referenz von
entfernten Objekten zu bekommen. Sie verwenden dann nicht mehr die lookup-Methode
der Naming-Klasse.
•
Nach dem Kompilieren Ihrer Klassen rufen Sie den RMI-Compiler mit der Option -iiop
auf:
> rmic -iiop KontoImpl
• Der Server wird wie folgt gestartet:
> java Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFa
ctory -Djava.security.policy=<POLICYFILE> Djava.naming.provider.url=iiop://<SERVER:PORTNR> KontoImpl
&
(Beachten Sie: der Server nimmt keinen Port-Parameter mehr entgegen, ändern Sie also
entpsrechend ihre main-Methode)
• Der Client wird analog zum Server gestartet
2.2 Ihre Aufgabe: Eine verteilte Anwendung mit RMI/IIOP
2.2.1 Szenario
Wir verwenden das gleiche Szenario wie in dem JRMP-Tutorial.
2.2.2 Code Beispiel
Quellcode-Beispiele für drei Dateien
•
•
•
KontoImpl.java,
Terminal.java,
Konto.java,
sowie eine Security-Policy-Datei sind im Anhang wiedergegeben.
2.2.3 Port Nummer
Server-Anwendungen erhalten Nachrichten über Ports. Das obige Beispiel verwendet Port-Nr.
2012.
Mehrere Studenten werden gleichzeitig dieses Tutorial bearbeiten. Wir benutzen auf Galadriel
aber keine Middleware wie z.B. WebSphere. Stattdessen startet jeder Benutzer auf Galadriel
seinen eigenen Server. Damit braucht jeder Benutzer für seinen Server eine eigene PortNummer.
Wir schlagen vor, dass Sie eine Port-Nr. im Bereich zwischen 50001 und 50999 wählen.
Um Konflikte mit anderen Benutzern zu vermeiden, schlagen wir vor, dass Sie als Port-Nr.
50xxx wählen, wobei xxx die drei letzten Ziffern Ihrer prak-User-ID sind. Wenn Sie also die
User-ID prak519 benutzen, wäre Ihre Port Nr. 50519.
Beachten Sie, dass die obigen Beispielprogramme Port Nr. 2012 benutzen. Sie müssen diese,
und auch überall sonst in diesem Text, durch Ihre eigene Port Nr. ersetzen.
− Bitte fahren Sie Vor Abschluss des Tutorials den von Ihnen gestarteten tnameservProzess wieder herunter!
2.2.4 Vorgehen
2.2.4.1 Benötigter Quellcode
Erstellen Sie ein eigenes leeres Verzeichnis auf Ihrem Rechner, z.B. iiop, und erstellen Sie die
3 java-Dateien
•
•
•
Konto.java
KontoImpl.java
Terminal.java
in diesem Verzeichnis, sowie zusätzlich die Security-Policy-Datei .
Hinweis:
Eine rudimentäre Implementierung, welche obigen Anforderungen genügt, reicht aus. Auf PIN,
Login, mehrere Kontos pro Server, Setzen/Prüfen der Kreditlinie, Zinsen usw. kann verzichtet
werden.
Wenn Sie wollen, können Sie dies natürlich trotzdem implementieren.
2.2.4.2 Das Interface und die Klassen kompilieren
Sie müssen die Klassen
•
•
•
Konto.class
KontoImpl.class
Terminal.class
mit Hilfe des javac-Compilers erzeugen. Hierfür brauchen Sie eine JavaEntwicklungsumgebung. Sie können (für die primitive Aufgabenstellung ausreichend) hierfür
die JDK benutzen, oder eine komfortablere Entwicklungsumgebung wie Eclipse einsetzen.
2.2.4.3. Java Kompatibilität
Genauso wie in dem JRMP-Tutorial lösen wir das Problem der inkompatiblen Java-Versionen,
indem wir das Kompilieren aller Klassen auf dem Server durchführen, und die Client-Klassen
anschließend in die Workstation laden.
2.2.4.4. Stubs und Skeletons mit rmic erstellen.
Mit Hilfe der Schnittstellenbeschreibung ist es möglich, Stubs und Skeletons zu erstellen.
Dies geschieht mit Hilfe des rmic-Compilers. Das Java-Interface (in diesem Beispiel „Konto“)
Ihres Service-Implementation-Programms enthält alle Informationen, die der Compiler
benötigt.
Den rmic-Compiler müssen Sie mit mit der –iiop Option
rmic –iiop KontoImpl
aufrufen. Als Ergebnis werden iiop kompatible Stubs und Skeletons erstellt. Es sollten die
Dateien
_KontoImpl_Tie.class
_Kontol_Stub.class
zusätzlich erstellt werden. Die so entstandenen 5 class-Dateien
Konto.class
KontoImpl.class
Terminal.class
_KontoImpl_Tie.class
_Kontol_Stub.class
sind das Ergebnis.
Als nächste Schritte müssen diese Dateien jetzt erzeugt und dann ausgeführt werden.
3. Erstellen der Java-Klassen auf dem zLinux-Server
3.1 Laden der Java-Klassen auf den zLinux-Server
Die 4 Dateien
• Konto.java
• KontoImpl.java
• Terminal.java
• security.policy
müssen nun auf dem Server galadriel.cs.uni-tuebingen.de (oder 134.2.205.55) geladen werden.
Das Laden geschieht am Einfachsten mit WinSCP.
Wir arbeiten auch in diesem Tutorial mit einfachen Java-Klassen, keinen Servlets und EJBs.
An Stelle der komplexeren Web-Application-Server-Installation mit jar- und ear-Files genügt
ein einfaches Kopieren.
Kopieren Sie wie in dem JRMP-Tutorial das von Ihnen erstellte Verzeichnis iiop nach
Galadriel.
3.2 Zugriff auf zLinux
Als nächstes müssen wir den Quellcode kompilieren. Rufen Sie wieder PuTTY auf und loggen
Sie sich ein.
Java-Klassen sowie Stub und Tie werden erstellt.
Wir müssen auch hier definieren, welchen Port wir verwenden wollen. Ähnlich zur JavaRegistry brauchen wir einen Eintrag in einen Corba-Name-Service. Sie müssen daher vor dem
Aufruf des Servers (KontoImpl) auf Galadriel den Befehl tnameserv -ORBInitialPort
2012& eingeben.
tnameserv -ORBInitialPort 2012& ist das RMI/IIOP-Pendant zum JRMP-Registry-Aufruf
rmiregistry 2012& aus dem JRMP-Tutorial.
Der Corba-COS- (Common Object Services) Naming-Service besteht aus einer baumartigen
Ordner-Struktur für Object-References, vergleichbar mit der Ordner-Struktur für Dateien in
einem Linux-Dateisystem. Der Transient-Naming-Service tnameserv ist eine einfache
Implementierung der COSNaming-Service-Specifikation. Die Option -ORBInitialPort
spezifiziert die Portnummer, auf der der Server Nachrichten empfängt.
Das „&“ am Ende des Command-Strings bewirkt wie im JRMP-Tutorial, dass für die
Ausführung ein getrennter Hintergrundprozess gestartet wird. Die Ziffer 22629 ist die PID
(Prozess-ID.
Der Begriff IOR bedeutet Interoperable Object Reference. Eine IOR beschreibt eine
Objektreferenz auf ein Corba-Objekt. Der Corba-Naming-Service ist eine Möglichkeit zur
Speicherung von Objekt-Referenzen unter einem Namen. IOR und Name sind vergleichbar mit
DNS-IP-Adressen
(z.B. 134.2.205.55) und symbolischen Namen (z.B. galadriel.cs.uni-tuebingen.de). Während
aber IP-Adressen 32 Bit lang sind (128 Bit in Version 6), haben IORs typischerweise eine
Länge von mehreren 100 Hex-Zeichen. In unserem Fall ist die IOR etwa 300 Zeichen lang.
IP-Adressen werden vom NIC (oder DENIC) zentral verwaltet, während IORs vom
Programmierer frei vergeben werden. Die sehr langen IORs schließen die zufällige Erstellung
von Synonymen praktisch aus.
Ready bedeutet, dass der Naming-Service läuft.
<Enter> bringt uns zurück zum Prompt.
Als nächsten Schritt starten wir den KontoImpl-Server mit der Eingabe des folgenden
Kommandos:
java -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
-Djava.security.policy=security.policy
-Djava.naming.provider.url=iiop://galadriel.cs.uni-tuebingen.de:2012
KontoImpl
java KontoImpl ruft die Klasse KontoImpl.class auf. Dies geschieht über drei –Djava
Qualifier (Optionen). Djava-Qualifier werden benutzt, um Eigenschaften an die aufgerufene
JVM zu übergeben. In diesem Fall sind es die Eigenschaften
• naming.factory.initial
• security.policy
• naming.provider.url
denen die hinter dem Gleichheitszeichen stehenden Werte übergeben werden. Bei
Verwendung des Sun-JDKs ist com.sun.jndi.cosnaming.CNCtxFactory ein gültiger Wert
für die naming.factory.initial Eigenschaft.
Details zu Properties finden Sie unter
http://download.oracle.com/javase/tutorial/essential/environment/properties.html .
<Enter>, um das Kommando einzugeben.
Damit läuft auch unser Server und wartet auf eine Input Nachricht (über Port 2012).
Offnen sie jetzt ein zweites Eingabeaufforderungs-Fenster.
4. Ausführen des Programms
4.1 Download der Client-Klassen
Sie haben auf dem Server Galadriel gleichzeitig auch die vom Klienten benötigten Klassen
erzeugt. Kopieren Sie diese class-Dateien sowie Ihre security.policy auf Ihrem
Arbeitsplatzrechner in ein Verzeichnis Ihrer Wahl, in diesem Beispiel „Example“.
Stellen Sie sicher, dass die classpath-Umgebungsvariable Ihres Rechners den Namen
dieses Verzeichnisses enthält.
4.2 Aufruf des Servers
Sie haben nun ein ausführbares Java-RMI-Client-Programm auf ihrer Workstation, und ein
dazu passendes RMI-Server-Programm auf Galadriel. Sie können nun mit dem Client den
Server ansprechen.
Öffnen Sie auf Ihrem Arbeitsplatz-Rechner ein zweites Eingabeauforderungs-Fenster
(zusätzlich zu dem noch immer geöffneten PuTTy-Fenster). Die 4 Dateien befinden sich jetzt
auf dem Client in dem Verzeichnis Example.
Mit dem Kommando
java -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory Djava.security.policy=security.policy Djava.naming.provider.url=iiop://galadriel.cs.uni- tuebingen.de:2012
Terminal
wird der Client gestartet.
Das Ergebnis ist hier zu sehen. Schauen Sie in Ihren Quellcode und verifizieren Sie, dass das
Ergebnis Ihren Erwartungen entspricht.
Herzlichen Glückwunsch, you did it! Das Tutorial wurde erfolgreich durchgeführt.
4.3 Herunterfahren des Servers
Wichtig! Zum Abschluss ist jetzt der Server ordnungsgemäß herunterzufahren.
Strg+C beendet Ihren Server.
Bitte beenden Sie am Ende wieder Ihren gestarteten tnameserv!
Hierzu ps –aef eingeben.
den tnameserv Prozess mit dem kill <pid> Kommando stoppen. Die PID ist hier 22629.
Das PuTTY-Fenster kann nun geschlossen werden.
Das war es.
Aufgabe: Als Abgabe wird eine funktionierende Verison ihrer Anwendung inklusive Quellcode,
eine Prozessliste der laufenden Prozesse wenn das Programm arbeitet und eine
vollständige Prozessliste, wenn alle Programme beendet sind, sowie ein Screenshot
der Ausgabe der Main-Methode der Terminal-Klasse erwartet. Modifizieren Sie den
Quellcode, damit die Ausgabe auf dem Bildschirm etwas aussagekräftiger und/oder
benutzerfreundlicher aussieht.
5. Fragen
5.1 Nennen sie mindestens drei Unterschiede zu CORBA
•
•
•
•
•
RMI ist nur kompatibel zu Java während CORBA ein Standart für die meisten
Programmiersprachen ist (solange diese IDL unterstützten).
In CORBA müssen alle im Netzwerk verfügbaren Interfaces über IDL (Interface Definition
Language) beschrieben sein. In Java reicht die übliche native Definition von Interfaces aus.
RMI verwendet standardmäßig das JRMP (Java Remote Method Protocol); CORBA verwendet
das Internet-Inter-ORB-Protokoll. Dieses ist in den meisten Fällen leistungsfähiger als JRMP.
RMI-über-IIOP ist jedoch ebenfalls möglich (siehe Aufgabe RMI/IIOP).
Mit JRMP können Quellcode und Objekte über das Netz übertragen werden. In CORBA können
hingegen nur Datenstrukturen übertragen werden.
5.2 Nennen sie ein Beispielszenario bei welchem der RMIClassLoader
benötigt wird
•
•
Der RMIClassLoader wird in der Regel benötigt um Klassen aus entfernten Standorten über das
Netzwerk zu laden.
Wird beispielsweise eine bestimmte Klasse innerhalb eines Programms benötigt, so kann man
diese (manuell) mit Hilfe der Methode loadClass(URL,String) in das Programm laden.
5.3 Welche Vorteile gewinnt man durch die Nutzung von RMI-over-IIOP?
•
•
•
•
RMI-over-IIOP verbindet alle Vorteile von RMI und CORBA.
Es wird das leistungsstärkere IIOP als Übertragunsprotokoll verwendet.
Es können Quellcode und Objekte über das Netz übertragen werden.
Es muss kein IDL verwendet werden um mit Objekten anderer Programmiersprachen zu
kommunizieren, da das Interface nativ in Java definiert und mit Hilfe von rmic-idlin IDL
überführt werden kann.
5.4 Wofür steht JNDI? Wozu dient es?
•
•
•
Java Naming and Directory Interface.
Namens- und Verzeichnisdienst über das beispielsweise Objekte innerhalb einer
CORBA Anwendung gefunden werden können.
In der RMI/IIOP-Aufgabe beispielsweise wird die Klasse KontoImpl mit der Option Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory gestartet. Dabei
bedeutet der Wert com.sun.jndi.cosnaming.CNCtxFactory, dass es sich um einen
CORBA-Namensdienst handelt.
6. Anhang
--------------------------------------------------------------------------
6.1 KontoImpl.java
import java.rmi.*;
import java.rmi.server.*;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public class KontoImpl extends PortableRemoteObject implements Konto {
int kontostand;
protected KontoImpl() throws RemoteException {
this.kontostand=1000;
}
public String getKontostand() throws RemoteException {
return "Der aktuelle Kontostand ist "+kontostand;
}
public void auszahlung(int betrag) throws RemoteException {
kontostand=kontostand-betrag;
}
public void einzahlung(int betrag) throws RemoteException {
kontostand=kontostand+betrag;
}
public static void main (String[] args) throws RemoteException,
NamingException {
int port = (args.length > 0) ? Integer.parseInt(args[0]) : 2012;
KontoImpl obj = new KontoImpl();
String objName = "KontoObj";
InitialContext INC = new InitialContext();
if (System.getSecurityManager() == null) {
System.setSecurityManager (new RMISecurityManager());
}
INC.rebind(objName, obj);
System.out.println ("Konto ready.");
}
}
--------------------------------------------------------------------------
6.2 Terminal.java
import
import
import
import
import
java.net.MalformedURLException;
java.rmi.*;
java.rmi.server.*;
javax.naming.InitialContext;
javax.naming.NamingException;
public class Terminal {
static public void main (String[] args) throws MalformedURLException,
RemoteException, NotBoundException, NamingException {
String host = (args.length < 1) ? "galadriel.cs.uni-tuebingen.de"
://"127.0.0.1" :
args[0];
int port = (args.length < 2) ? 2012 : Integer.parseInt(args[1]);
try {
if (System.getSecurityManager() == null) {
System.setSecurityManager (new RMISecurityManager());
}
InitialContext INC = new InitialContext();
Konto obj = (Konto) INC.lookup("iiop://" + host + ":" + port +
"/" + "KontoObj");
System.out.println (obj.getKontostand());
obj.einzahlung(30);
System.out.println (obj.getKontostand());
obj.auszahlung(30);
System.out.println (obj.getKontostand());
}
catch(Exception e) {
System.out.println ("Terminal failed, caught exception " +
e.getMessage());
}
}
}
--------------------------------------------------------------------------
--------------------------------------------------------------------------
6.3 Konto.java
import java.rmi.*;
public
public
public
public
}
interface Konto extends Remote {
String getKontostand() throws RemoteException;
void einzahlung(int betrag) throws RemoteException;
void auszahlung(int betrag) throws RemoteException;
--------------------------------------------------------------------------
6.4 security.policy
grant {
permission java.security.AllPermission;
};
--------------------------------------------------------------------------
Herunterladen