Java Native Interface Eine Einführung anhand eines praktischen Beispiels
description
Transcript of Java Native Interface Eine Einführung anhand eines praktischen Beispiels
Java Native Interface Eine Einführung anhand eines
praktischen Beispiels
Fachseminar WS 09
Cornelius Zühl
Jeder verwendet JNI 1(der Java Programme nutzt)
Initialisieren der VM Windows Unix
Methoden des Java-Frameworks, z.B. aus „System“ verwenden JNI
Jeder verwendet JNI 2(der Java Programme schreibt)
Das Schlüsselwort „native“, aber warum kann ICH es verwenden? 1 Ein „echter“ und ein „scheinbarer“ Grund Grund 1
Steigerung der Geschwindigkeit Einige Aufgaben der Java-Release werden nicht
in derselben Weise wie optimierte C-Programme ausgeführt
Konkret Kritische Stellen (z.B. innere Schleifen) auslagern
und in einer Java-Shell wrappen um so den „Trick“ vor dem Benutzer zu verbergen
Das Schlüsselwort „native“, aber warum kann ICH es verwenden? 2 Ein „echter“ und ein „scheinbarer“ Grund Grund 2
Ermöglicht Zugang zu speziellen Fähigkeiten des Rechners / Betriebssystem (BS)
Anschluss an neue Peripheriegeräte / Steckkarten Zugriff auf verschiedene Netztypen Verwendung eines eindeutigen Merkmals des BS
Konkret Erfassen von Echtzeitton über Mikrofon
Das Schlüsselwort „native“, aber warum kann ICH es verwenden? 3 Ein „echter“ und ein „scheinbarer“ Grund
Grund – Performancesteigerung
Grund – Spezielle Eigenheiten des BS verwenden
Performancesteigerung als scheinbarer Grund Wer echtzeitkritisch will, wird Alternativen
verwenden Viele zeitkritische Probleme ohnehin schon in
der JVM nativ gelöst
Besser Energie auf gutes Design von Klassen und Methoden verwenden Abstrakt und wieder verwendbar
Geschwindigkeit als letzter Schritt
Nativ spricht Java
Erzeugen, untersuchen und ändern von Java Objekten (einschließlich Arrays und Strings)
Java Methoden aufrufen Exceptions werfen und fangen Klassen und Klasseninformationen laden Typprüfung zur Laufzeit
Auch erzeugen einer VM über Invocation API möglich
Ein Blick hinter die Kulissen 1
Aufruf nativ JVM über Interface Pointer IP = Zeiger auf Zeiger auf Array von
Funktionszeigern Pro (Java)Aufruf-Thread ist IP garantiert gleich
Funktionszeiger an Vordefinierte Stellen im Array, genannt JNI Funktionen
Ein Blick hinter die Kulissen 2struct JNINativeInterface_ {
void *reserved0; void *reserved1; void *reserved2; void *reserved3; ...
jfieldID (JNICALL *GetStaticFieldID) (JNIEnv *env, jclass clazz, const char *name, const char *sig);…
}
struct JNIEnv_ { const struct JNINativeInterface_ *functions;
...jfieldID GetStaticFieldID(jclass clazz, const char *name, const char *sig) { return functions->GetStaticFieldID(this,clazz,name,sig);}
…}
Ein Blick hinter die Kulissen 3
Spezielle Namenskonvention für externe d.h. native deklarierte „Java“ Methoden
Auf nicht Java Seite erhalten Methoden immer zwei zusätzliche Argumente Argument eins ist der JNI Interface Pointer Argument zwei ist bei static native Methoden
Zeiger auf Java-Klasse in JVM Argument zwei ist bei nonstatic native Methoden
Zeiger auf Java-Objekt („this“) in JVM
Ein Blick hinter die Kulissen 4Was macht der Garbage Collector auf der nativen Seite? Primitive werden kopiert Java-Objekte „by reference“ übergeben
Unterteilung in lokale / globale Referenzen Lokale Referenzen leben im Scope ihres erzeugendem
Stack-Frame und Thread gelöscht ab „return“ (Vorsicht, JVM hat begrenzten Speicher um sich lokale Referenzen zu merken!)
Globale Referenzen leben bis sie explizit freigegeben werden
Lokale Referenzen können in globale umgewandelt werden
JNI Funktionen geben lokale Referenzen zurück
Ein Blick hinter die Kulissen 5 Wohin mit Fehlern?
JNI Funktionen geben Fehlercodes Können mit ExceptionOccoured() abgefragt
werden Zwei Arten des Exceptionhandlings
Die native Methode kehrt zurück Exception wird im Javacode geworfen
Die native Methode ruft ExceptionClear() auf und kümmert sich selbst um das Exceptionhandling
Der Weg zur Verwendung 1
Voraussetzungen um native Methoden zu nutzen Deklaration – auf Java Seite Implementierung – als externe Einstiegspunkte in
binären Bibliotheken JNI stellt die Möglichkeit eines „call back“ auf die
aufrufende JVM bereit Laden – der Bibliothek (typischerweise im „static
initializer“ der Java Klasse die „native“ verwendet) System.load(…) oder System.loadLibrary(…)
Der Weg zur Verwendung 2 Deklaration – auf Java Seite
Vorbereitung zum Erstellen der Headerdatei für native Seite set JAVA_HOME=C:\Programme\Java\jdk1.6.0_XX set PATH=%PATH%;%JAVA_HOME%\bin C:\PROJECT_PATH\bin>javap -private -s de.package.jni.Klasse
Der Weg zur Verwendung 3 Implementierung – auf native Seite
Inkludieren der Headerdatei „<jni.h>“ Gemäß der Namenskonvention muss eine
Funktionsdeklaration geschrieben werden
Geht’s auch einfacher??
JNIEXPORT jboolean JNICALL
Java_de_paket_jni_Klasse_callNative , jint);(JNIEnv *, jobject
Der Weg zur Verwendung 4 Implementierung – auf native Seite
Kommandozeilentool zum Erzeugen der Headerdatei set JAVA_HOME=C:\Programme\Java\jdk1.6.0_XX set PATH=%PATH%;%JAVA_HOME%\bin C:\PROJECT_PATH\bin>javah de.package.jni.Klasse
Der Weg zur Verwendung 5 Laden – der Bibliothek
DEMO
Quellen
IBM Understanding the Java Native Interface http://publib.boulder.ibm.com/infocenter/javasdk/v6r0/topic/com.ibm.java.doc.diagnostics.60/html/jni.html#jni
Native Methoden und Bibliotheken (1997) http://olymp.idle.at/~apollo/books/Java%20in%2021%20Tagen/kap20.htm
JNI 1.1 Specification ff. http://java.sun.com/j2se/1.4.2/docs/guide/jni/
Gute Übersicht für den Praktischen Einsatz http://www.haertfelder.com/jni.html