JNI_Java Native Interface

Werbung
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
Jeder verwendet JNI 2
(der Java Programme schreibt)

Methoden des Java-Frameworks, z.B. aus
„System“ verwenden JNI
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 2
struct 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 4
Was 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
JNIEXPORT jboolean JNICALL
Java_de_paket_jni_Klasse_callNative (JNIEnv *, jobject, jint);

Geht’s auch einfacher??
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


Native Methoden und Bibliotheken (1997)


http://olymp.idle.at/~apollo/books/Java%20in%2021%20Tagen/kap20.htm
JNI 1.1 Specification ff.


http://publib.boulder.ibm.com/infocenter/javasdk/v6r0/topic/com.ibm.java.doc.diagnostics.60/html/jni.html#jni
http://java.sun.com/j2se/1.4.2/docs/guide/jni/
Gute Übersicht für den Praktischen Einsatz

http://www.haertfelder.com/jni.html
Herunterladen