JNI verbindet Java mit den systemnahen Programmiersprachen C und C++, indem es Aufrufe in beiden Richtungen erlaubt.
Nicht ganz minimal und ziemlich sinnlos, aber interessant.
Das Beispiel ruft eine C-Funktion auf, welche wiederum die
Methode System.out.println
verwendet, um den
bekannten Gruß auszugeben.
public class Hello { public static void main (String[] args) { new Hello().print(); } private native void print (); static { System.loadLibrary ("Hello"); } }
Anschließend übersetzt man dieses Java-Programm und extrahiert eine Header-Datei:
class=Hello javac $class.java javah -jni $class
Jetzt fehlt nur noch die Implementierung der soeben erzeugten Schnittstelle in C:
#include "Hello.h" #include <stdio.h> JNIEXPORT void JNICALL Java_Hello_print (JNIEnv * env, jobject self) { printf ("Hello, C!\n"); jclass system = (*env)->FindClass (env, "java/lang/System"); jfieldID id = (*env)->GetStaticFieldID (env, system, "out", "Ljava/io/PrintStream;"); jobject obj = (*env)->GetStaticObjectField (env, system, id); jclass cls = (*env)->GetObjectClass (env, obj); jmethodID println = (*env)->GetMethodID (env, cls, "println", "(Ljava/lang/String;)V"); jobject hello = (*env)->NewStringUTF (env, "Namaste, Java!"); // Call java.lang.System.out.println (hello); (*env)->CallVoidMethod (env, obj, println, hello); printf ("Goodbye, C!\n"); }
Der Übersetzer erzeugt aus dieser Datei eine dynamisch ladbare
Bibliothek namens libHello.so
, welche die
JVM
laden und verwenden kann.
gcc -g -Wall -fPIC -I/usr/lib/jvm/java-7-openjdk-amd64/include -c -o $class.o $class.c gcc -lc $class.o -shared -W1,soname,$class -o lib$class.so java -Djava.library.path=. $class Hello, C! Namaste, Java! Goodbye, C!
Ein Felddeskriptor identifiziert Parameter, Rückgabewert und Methoden-Signatur.
Deskriptor | Type | NativeType | Beschreibung |
Void | |||
Z | Boolean | jboolean | Wahrheitswert |
B | Byte | jbyte | Speicherzelle |
C | Char | jchar | Unicodepunkt |
S | Short | jshort | Kleine Zahl (16 Bit) |
I | Int | jint | Zahl (32 Bit) |
J | Long | jlong | Große Zahl (64 Bit) |
F | Float | jfloat | Ungenaue Gleitpunktzahl |
D | Double | jdouble | Gleitpunktzahl |
LPackage/…/Object | Object | jobject | Objekt |
[Field | Array | Reihung | |
(Field,…)ReturnType | Method | Methode |
Die Klasse JNIEnv
dient als Schnittstelle zur Java
Laufzeitumgebung. Sie ermöglicht es, Klassen zu erzeugen, zu suchen,
zu laden, zu modifizieren und Methoden aufzurufen.
JNIEnv | |||
jint | GetVersion | () | |
jint | GetJavaVM | (JavaVM **) | |
Klasse | |||
---|---|---|---|
jclass | DefineClass | (const char * class, jobject loader, jbyte buf, jsize len) | |
jclass | FindClass | (const char * class) | |
jclass | GetSuperclass | (jclass) | |
jboolean | IsAssignableFrom | (jclass, jclass) | |
Objekt | |||
jobject | AllocObject | (jclass) | |
jobject | NewObject | (jclass, jmethodID constructor, ...) | |
jclass | GetObjectClass | (jobject) | |
jboolean | IsInstanceOf | (jobject, jclass) | |
jboolean | IsSameObject | (jobject, jobject) | |
Feld | |||
jfieldID | GetFieldID | (jclass, const char * name, const char * field) | |
jfieldID | GetStaticFieldID | (jclass, const char * name, const char * field) | |
NativeType | GetTypeField | (jobject, jfieldID) | |
SetTypeField | (jobject, jfieldID, NativeType) | ||
NativeType | GetStaticTypeField | (jclass, jfieldID) | |
SetStaticTypeField | (jclass, jfieldID, NativeType) | ||
Methode | |||
jmethodID | GetMethodID | (jclass, const char * name, const char * method) | |
jmethodID | GetStaticMethodID | (jclass, const char * name, const char * method) | |
NativeType | CallStaticTypeMethod | (jclass, jmethodID, ...) | |
NativeType | CallTypeMethod | (jobject, jmethodID, ...) | |
NativeType | CallTypeMethodA | (jobject, jmethodID, jvalue *) | |
NativeType | CallTypeMethodV | (jobject, jmethodID, va_list) | |
NativeType | CallNonvirtualTypeMethod | (jobject, jclass, jmethodID) | |
Zeichenkette | |||
jstring | NewString | (const jchar *, jsize) | |
jstring | NewStringUTF | (const char *) | |
jsize | GetStringLength | (jstring) | |
jsize | GetStringLengthUTF | (jstring) | |
const jchar * | GetStringChars | (jstring, jboolean *) | |
const jbyte * | GetStringUTFChars | (jstring, jboolean *) | |
const jchar * | GetStringCritical | (jstring, jboolean *) | |
GetStringRegion | (jstring, jsize start, jsize len, jchar * buf) | ||
GetStringUTFRegion | (jstring, jsize start, jsize len, jchar * buf) | ||
ReleaseStringChars | (jstring, const jchar *) | ||
ReleaseStringCritical | (jstring, const jchar *) | ||
ReleaseStringUTFChars | (jstring, const char *) | ||
Reihung | |||
jarray | NewObjectArray | (jsize, jclass, jobject) | |
ArrayType | NewTypeArray | (jsize) | |
jsize | GetArrayLength | (jarray) | |
NativeType | GetTypeArrayElements | (ArrayType, jboolean *) | |
GetTypeArrayRegion | (ArrayType, jsize start, jsize len, NativeType * buf) | ||
SetTypeArrayRegion | (ArrayType, jsize start, jsize len, NativeType * buf) | ||
GetTypeField | (ArrayType, jfieldID) | ||
jobject | GetObjectArrayElement | (jobjectArray, jsize) | |
SetObjectArrayElement | (jobjectArray, jsize, jobject) | ||
void * | GetPrimitiveArrayCritical | (jarray, jboolean *) | |
ReleasePrimitiveArrayCritical | (jarray, void *, jint mode) | ||
ReleaseTypeArrayElements | (ArrayType, NativeType *, jint mode) | ||
Ausnahme | |||
jint | Throw | (jthrowable) | |
ThrowNew | (jclass, const char *) | ||
jthrowable | ExceptionOccurred | () | |
ExceptionDescribe | () | ||
jboolean | ExceptionCheck | () | |
jint | ExceptionClear | (jint) | |
FatalError | (const char *) | ||
Verweis | |||
jobject | NewLocalRef | (jobject) | |
jobject | NewGlobalRef | (jobject) | |
jweak | NewWeakGlobalRef | (jobject) | |
DeleteLocalRef | (jobject) | ||
DeleteGlobalRef | (jobject) | ||
DeleteWeakGlobalRef | (jobject) | ||
Reflexion | |||
jfieldID | FromReflectedField | (jobject) | |
jmethodID | FromReflectedMethod | (jobject) | |
jobject | ToReflectedField | (jclass, jfieldID, jboolean) | |
jobject | ToReflectedMethod | (jclass, jmethodID, jboolean) | |
Sonstiges | |||
RegisterNatives | (jclass, const JNINativeMethod *, jint) | ||
jint | UnregisterNatives | (jclass) | |
jint | MonitorEnter | (jobject) | |
jint | MonitorExit | (jobject) | |
jint | EnsureLocalCapacity | (jint) | |
jint | PushLocalFrame | (jint) | |
jobject | PopLocalFrame | (jobject) |
META-INF
Datum | Version | Codename | Neuerungen |
1995 | JDK Beta | - | Entwicklungsversionen |
1996-01-23 | JDK 1.0 | Oak | Erstveröffentlichung |
1997-02-19 | JDK 1.1 | - | Innere Klassen, AWT, RMI, JDBC |
1998-12-08 | J2SE 1.2 | Playground | Swing, CORBA & IDL |
2000-05-08 | J2SE 1.3 | Kestrel | HotSpot JVM |
2002-02-06 | J2SE 1.4 | Merlin | Parser und Werkzeuge für XML |
2004-09-30 | J2SE 5.0 | Tiger | Generics, Annotations, Autoboxing, Enumerations |
2006-12-11 | Java SE 6 | Mustang | Übernahme durch Oracle, Leistungsoptimierung |
2011-07-28 | Java SE 7 | Dolphin | NIO, Unterstützung dynmaischer Sprachen |
2014-03-18 | Java SE 8 | - | Lambda-Ausdrücke |