Projekt: RMI RPC und JNI

Werbung
Projekt: RMI RPC und JNI
Systemprogrammierung
Wintersemester 2007/2008
Systemprogrammierung Wintersemester 2007/2008
Teilnehmer
Abdelkarim Kodssi
Schwerpunkt: RMI und RPC
U-Yeol Suk
Schwerpunkt: JNI
Systemprogrammierung Wintersemester 2007/2008
• Kapitel 1 RMI und RPC
• Kapitel 2 JNI
Systemprogrammierung Wintersemester 2007/2008
Java RMI
Kapitel 1.RMI
-Was ist RMI?
-Ziele von RMI
-RPC
-Unterschied zu RPC
Kapitel 1.2 Funktionsweise von RMI
-RMI Kommunikations-Architektur
-RMI Elemente und Ablauf
Kapitel 1.3 Code Beispiele
-Remote Interface definieren
-Remote-Object implementieren
-Server implementieren
-Client implementieren
Systemprogrammierung Wintersemester 2007/2008
1.RMI
ØWas ist RMI?
ü RMI steht für Remote Method Invocation (entfernter
Methodenaufruf)
ü Realisiert Client-Server Modell
ü RMI läuft nur auf Java rechner
ü Basiert auf dem Prinzip von RPC ( remote procedur call )
Systemprogrammierung Wintersemester 2007/2008
1.RMI
ØZiele von RMI
ü Den Anwendungsprogrammierer hierbei zu unterstützen und ihm
die aufwendige und fehleranfällige Implementierung eines solchen
Protokolls abzunehmen.
ü Zu den indirekten Zielen von RMI gehört es Lastausgleich von
Programmen zu ermöglichen, sowie die Skalierbarkeit von
Programmen zu erhöhen.
Systemprogrammierung Wintersemester 2007/2008
1.RMI
ØRPC
Abb. 1 RPC Prinzip
Systemprogrammierung Wintersemester 2007/2008
1.RMI
ØRPC
ü RPC steht für Remote Procedure Call und wurde 1983
vorgestellt
ü Den Zugriff auf entfernte Serverfunktionen aussehen zu
lassen und so die Komplexität der Netzwerkprogrammierung
vor den Anwendungsprogrammierer zu verbergen
ü Die eigentliche Verbindung zwischen Server und Client
übernehmen sog. Stellvertreterobjekte (engl. proxies).
Systemprogrammierung Wintersemester 2007/2008
1.RMI
ØUnterschied zu RPC
ü RPC und RMI scheinen identisch zu sein, beide
arbeiten mit Sockets
ü RPC ist nicht für objektorientiertes Arbeiten
geeignet
Systemprogrammierung Wintersemester 2007/2008
1.2 Funktionsweise von RMI
ØRMI Kommunikations-Architektur
Abb. 2 RMI Kommunikations-Architektur
Systemprogrammierung Wintersemester 2007/2008
1.2 Funktionsweise von RMI
ØRMI Kommunikations-Architektur
üDie Transportschicht (Netzwerverbindung) umfasst hierbei das
Host OS, den sog. Networklayer und das Netzwerkkabel.
üDas Remote Reference Layer umfasst die Verbindungs-Semantik,
d.h. es implementiert die Übertragungsprotokolle und die
Verbindungsdetails.
üStub/Skeleton Schicht verbirgt die komplizierten Details der
Kommunikation.
Systemprogrammierung Wintersemester 2007/2008
1.2 Funktionsweise von RMI
ØRMI Elemente
ü Das Remote-Interface definiert die Funktionen, die auf dem
Server zur Verfügung stehen sollen und Beschreibt damit das
Verhalten derentfernten Funktionen (ohne dieses Verhalten zu
implementieren).
ü Die Remote-Objekte implementieren das Remote-Interface und
das Verhalten der entfernten Funktionen.
Systemprogrammierung Wintersemester 2007/2008
1.2 Funktionsweise von RMI
ØRMI Elemente
ü Beim Namens-Dienst (RMI Registry) werden die Remote-Objekte
vom Server registriert und die Referenzen auf diese RemoteObjekte können von den Clients abgefragt werden.
ü Als Remote-Referenzen werden die Referenzen auf Remote-
Objekte bezeichnet.
Systemprogrammierung Wintersemester 2007/2008
1.2 Funktionsweise von RMI
ØRMI Elemente und Ablauf
Abb. 3 RMI: Elemente und Ablauf
Systemprogrammierung Wintersemester 2007/2008
1.2 Funktionsweise von RMI
Ø
RMI Ablauf
Der Ablauf lässt sich damit wie folgt beschreiben:
ü
Zuerst wird die RMI Registry mit dem Befehl $ start rmiregistry
über die Befehlskonsole auf dem Server gestartet.
ü
Danach instanziiert der Server ein oder mehrere Remote-Objekte
und meldet diese mit der Funktion Naming.bind(), die
Bestandteil des RMI-Pakets ist, bei der RMI Registry an.
Systemprogrammierung Wintersemester 2007/2008
1.2 Funktionsweise von RMI
Ø
RMI Ablauf
ü
Im dritten Schritt erfragt der Client mit der Funktion
Naming.lookup() von der RMI Registry eine Referenz auf das
entfernte Objekt und ist danach in der Lage auf dieses
zuzugreifen.
ü
Jetzt kann der Client die entfernte Funktion aufrufen und erhält
ü
im fünften und letzten Schritt den Rückgabewert bzw. eine
Exception zurück, wenn bei der Kommunikation ein Fehler
aufgetreten ist.
Systemprogrammierung Wintersemester 2007/2008
1.3 Code Beispiele
Abb. 4 Implementierungsschritte
Abbildung soll einen Überblick über die einzelnen Schritte bei der
Implementierung geben und die relevanten Elemente hervorheben.
Systemprogrammierung Wintersemester 2007/2008
1.3 Code Beispiele
ØRemote Interface definieren
Das Remote-Interface definiert die Funktionen, die auf dem
Server zur Verfügung stehen sollen.
import java.rmi.*;
public interface Adder extends Remote
{
int add( int x, int y ) throws RemoteException;
}
Systemprogrammierung Wintersemester 2007/2008
1.3 Code Beispiele
ØImplementierung des Remote-Interface
Das Remote-Object implementiert das Verhalten der
entfernten Funktionen
public class AdderImpl extends UnicastRemoteObject implements
Adder
{
public AdderImpl()throws RemoteException{}
public int add( int x, int y ) throws RemoteException
{
return x + y;
}
}
Systemprogrammierung Wintersemester 2007/2008
1.3 Code Beispiele
ØServer Implementieren
Der Server ist ein „normales“ Java-Programm
public class Server
{
public static void main( String[] args )
{
try {
AdderImpl adder = new AdderImpl();
Naming.bind("Adder",adder );
} catch(Exception e)
{
// Registrieren des Remote-Objects fehlgeschlagen
}
}
System.out.println("Adder angemeldet");
}
Systemprogrammierung Wintersemester 2007/2008
1.3 Code Beispiele
ØClient implementieren
import java.rmi.*;
public class Client
{
public static void main( String[] args )
{
try{
Adder adder = (Adder) Naming.lookup( "Adder" );
System.out.println( adder.add( 49, 11 ) );
} catch(Exception e) {
// Zugriff auf Remote-Object fehlgeschlagen
}
}
}
Systemprogrammierung Wintersemester 2007/2008
1.3 Code Beispiele
ØRMI-Registry starten
• Vor dem Start der Anwendung ist die rmiregistry zu starten
mit Hilfe des rmiregistry-Kommandos. Rmiregistry ist eine
einfacher Server-seitiger Namensdienst:
ü Auf UNIX-basierten Systemen: rmiregistry & [PORT]
ü Auf Windows-Systemen: start rmiregistry [PORT]
Systemprogrammierung Wintersemester 2007/2008
Java Native Interface (JNI)
• Kapitel 2.1
Was ist JNI?
• Kapitel 2.2
−
−
−
−
Vorgehensweise beim Erstellen des JNI-Programms
Erstellen der Java-Klassen
Compilieren der Java-Klasse
Erzeugen der Headerdateien aus den Java-Klassen
−
−
−
−
−
−
Implementierung der Methode in C
Kompilieren der C-Funktionen
Parameter Übergabe in JNI
JNI Sinaturen
Strings
C ruft Java-Methode auf
Kapitel 2.3
• Fazit
• Quelle für RMI ,RPC und JNI
Systemprogrammierung Wintersemester 2007/2008
2.1 Was ist JNI?
Bei JNI handelt es sich um eine Schnittstelle der JVM.
Diese ermöglicht den wechselseitigen Zugriff zwischen
Java-Anwendungen auf der einen und
plattformspezifischen (nativen) Bibliotheken und
Anwendungen auf der anderen Seite.
Dies ist in folgenden Situationen sinnvoll:
• Die Java Class Library unterstützt gewisse plattformabhängige
Features nicht, die Ihre Applikation benötigt.
• Es existiert bereits eine Library in einer anderen
Programmiersprache und Sie wollen diese Funktionen beliebigen JavaApplikationen zugänglich machen.
• Ihre Applikation enthält Teile, die zeitkritisch sind.
Systemprogrammierung Wintersemester 2007/2008
2.2 Vorgehensweise beim Erstellen des JNI-Programms
1Erstellen der Java Klassen
Prog.java
2. Compilieren
3. Header-File erzeugen
prog.h
4. Schreiben des C Programmes
Prog.class
prog.C
jni.h
5. Compilieren des C/C++ Programmes
6. Starten des
Programmes
prog.dll
Systemprogrammierung Wintersemester 2007/2008
2.2 Erstellen der Java-Klassen
• Deklarieren der nativen Methoden
private static native double callnative(
int input_i, String input_str, float input_f );
• Laden der c-Library in die Java-Klassen
static {
System.loadLibrary(„add);
}
Nach Aufruf der loadLibrary Funkt. kann die Methode
private static native double callnative() aufgerufen werden.
2.2 Erstellen der Java-Klassen
class Prog {
static int i = 2;
static float f = (float)3.50;
static double d = 0.20;
static String str = "Vorher";
//Deklarieren der native Methoden
private static native double callnative(int input_i, String input_str, float
input_f);
public static void main(String[] args) {
double erg = callnative(i, str, f);
System.out.println(„Ergebnis =" + erg);
}
static {
System.loadLibrary(„add");
}
}
2.2 Erstellen der Java-Klassen
• Eine Alternative zu loadLibrary(String) ist die
Methode load(String).
• Im Gegensatz zu loadLibrary() erwartet load()
einen absoluten Pfad zur Bibliothek.
Systemprogrammierung Wintersemester 2007/2008
2.2 Compilieren des Java-Programm
Der Befehl
javac Prog.java
erzeugt das class-File
Prog.class
Systemprogrammierung Wintersemester 2007/2008
2.2 Header Files aus den Java-Klassen erzeugen
Der Befehl
javah -jni prog.h Prog
erzeugt das Header-File
prog.h
Systemprogrammierung Wintersemester 2007/2008
2.2 Header Files aus den Java-Klassen erzeugen
#include <jni.h> /* Header for Java_Prog_callnative */
#ifndef _Included_Prog_callnative
#define _Included_Prog_callnative
#ifdef __cplusplus
extern "C" {
#endif
…
/*
Class: Prog
* Method: callnative
* Signature: (I, F, Ljava/lang/String;" )D
*/
…
JNIEXPORT jdouble JNICALL Java__Prog_callnative
(JNIEnv *env, jclass input_cls, jint input_int, jstring input_string, jfloat input_float);
#ifdef __cplusplus
}
#endif
#endif
Systemprogrammierung Wintersemester 2007/2008
2.2 Header Files aus den Java-Klassen erzeugen
Deklaration der Übergangsparameter der Funkt.
Callnative in der Headerdatei prog.h
JNIEXPORT jdouble JNICALL Java__Prog_callnative
(JNIEnv *env, jclass input_cls, jint input_int, jstring
input_string, jfloat input_float);
Der Übergabeparameter JNIEnv *env ist als ein Zeiger auf
das JNI-Environment-Interface zu verstehen.
Durch diesen Pointer kann man von C aus auf die JNI
Methoden zugreifen.
Systemprogrammierung Wintersemester 2007/2008
2.3 Implementierung der Methode in C
/*add.c*/
#include <stdio.h>
#include <math.h>
#include <jni.h>
#include „prog.h"
JNIEXPORT jdouble JNICALL Java_Prog_callnative(JNIEnv *env, jclass
input_cls, jint input_int, jstring input_string, jfloat input_float)
Systemprogrammierung Wintersemester 2007/2008
2.3 Implementierung der Methode in C
{
/* Java_String in C_String konvertieren und an C_Variable zuweisen */
const char *c_string = (*env)->GetStringUTFChars(env, input_string, 0);
/* Adresse des Feldes „d" in der der aufrufenden Klasse lokalisieren: */
jfieldID jfid = (*env)->GetStaticFieldID(env, input_cls, „d", "D");
/* Wert des Feldes „d" aus der aufrufenden Klasse auslesen: */
double input_double = (*env)->GetStaticDoubleField(env, input_cls, jfid);
printf("%s %lf + pow(%d,%f)\n", c_string, input_double, input_int, input_float);
return (input_double + pow(input_int, input_float));
}
2.3 Kompilieren der C-Funktion
• Testprogramm unter Linux aus der C-Quellcode Datei
add.c die shared library add.so generiert:
gcc -shared -l/usr/local/java/include l/usr/local/java/include/linux add.c -o libadd.so
2.3 Kompilieren der C-Funktion
• Unter Windows wurde die Library add.dll mit folgendem
Aufruf des Microsoft Visual C++ Compilers erstellt:
cl -Ic:\java\include -Ic:\java\include\win32 MD -LD add.c -Feadd.dll
Systemprogrammierung Wintersemester 2007/2008
2.3 Parameter Übergabe in JNI
Folgende Tabelle gibt Aufschluss wie die Java-Datentypen
in C gesehen werden:
Java Typ
•
•
•
•
•
•
•
•
•
boolean
byte
char
short
int
long
float
double
void
Native C-Typ
jboolean
jbyte
jchar
jshort
jint
jlong
jfloat
jdouble
void
unsigned, 8 bit
signed, 8 bit
unsigned, 16 bit
signed, 16 bit
signed, 32 bit
signed, 64 bit
32 bit
64 bit
Systemprogrammierung Wintersemester 2007/2008
2.3 Die JNI Signaturen
Java Typ
• boolean
• byte
• char
• short
• int
• long
• float
• double
• fully-qualified-class
• type[]
• method type
• void
Signatur
• Z
• B
• C
• S
• I
• J
• F
• D
• L fully-qualified-class
• [ type
• (arg-types) reg-type
• V
Beispiel: (IJDF)Z ist die Signatur einer Methode, welche vier Argumente (
int, long, double, float) hat und einen boole‘schen Wert zurückgibt.
Systemprogrammierung Wintersemester 2007/2008
2.3 Java Strings
JNI benutzt eine UTF-Codierung um Strings plattformunäbhangig
darzustellen.
Für die Verarbeitung von UTF Strings stehen in der jni-Library die
folgenden C Methoden zur Verfügung:
· jstring NewStringUTF(const char* bytes)
erzeugt ein neues java.lang.String Objekt.
· const jbyte* GetStringUTFChars(jstring string, jboolean* isCopy)
gibt einen Pointer auf einen Array von UTF-Characters zurück.
· void ReleaseStringUTFChars(jstring string, const char* str)
gibt den (neu alloziierten) Speicherplatz für str frei.
Systemprogrammierung Wintersemester 2007/2008
2.3 Aufruf von Java Methoden aus C
• GetObjectClass(jobject obj)
gibt die Klasse des Objektes obj zurück.
• jmethodID GetMethodID( jclass class, const char*
name, const char* sig)
gibt die Methoden-Nummer der Methodenname
der Klasse mit Signatur sig zurück.
Call<Type>Method( jobject obj, jmethodID methodID, para1 usw... )
Systemprogrammierung Wintersemester 2007/2008
2.3 Aufruf von Java Methoden aus C
Beispiel Code:
JNIEXPORT void JNICALL Java_MyFrame_process(JNIEnv
*env,jobject obj, jstring string)
{
const char *str = env->GetStringUTFChars(string, 0);
len = strlen(str);
jclass jmf = env->GetObjectClass( obj );
jmethodID mid = env->GetMethodID( jmf, "setLength", "(I)V" );
env->CallVoidMethod( obj, mid, (jint)len );
}
Systemprogrammierung Wintersemester 2007/2008
Fazit
Die Beispiele haben gezeigt, wie mit JNI Zugriffe zwischen
na-tiver Welt und Java-Welt bewerkstelligt werden können und
wie daraus resultierenden typischen
Implementierungsproblemen begegnet werden kann. Das JNI
kann insbesondere bei der Entwicklung von Systemsoftware
große Dienste leisten, es bietet der nativen Seite vielfältige
Möglichkeiten, die Java-Plattform zu nutzen.
Doch neben den Vorteilen sind auch Risiken zu nennen. Da
sowohl native Anwendungsteile als auch die JVM im gleichen
Adressraum laufen, führt z. B. eine Zugriffsverletzung auf
na-tiver Seite auch zum Absturz der JVM. Die Verwendung des
JNI setzt also sowohl eine tiefere Kenntnis der JVM als auch der
Zielplattform voraus.
Quelle für JNI
•
•
•
•
•
•
http://java.sun.com/products/jdk/1.2/docs/guide/jni/index.html
http://java.sun.com/docs/books/tutorial/native1.1/index.html
http://ringlord.com/platform/java/jni-howto.html
http://www.javaworld.com/javaworld/jw-10-1999/jw-10-jni.html
http://codeguru.developer.com/java/JNI/index.shtml
http://mindprod.com/jni.html
Quelle für RMI RPC
• Internet
http://java.sun.com/javase/technologies/core/basic/rmi/index.jsp
http://java.sun.com/j2se/1.4.2/docs/guide/rmi/getstart.doc.html
http://www.lrzmuenchen.de/services/compute/linuxcluster/cpjava/rmi.html
http://www.mm.informatik.tu-darmstadt.de/courses/helpdesk/rmi_tutorial.html
http://www.bs.informatik.uni-siegen.de/www/lehre/ws0506/csp/index_html
http://www.commentcamarche.net/rmi/rmiintro.php3
• Literatur
• Java Enterprise In A Nutshell (ISBN 3-89721-334-6)
• J2EE und Jboss Verteilte Enterprise Applikation auf der Basis von J2EE,JBoss &
Eclipse (ISBN 3-446-40508-9)
Herunterladen