Betriebssysteme Studiengang Informatik Dipl.-Inf., Dipl.-Ing. (FH) Michael Wilhelm Hochschule Harz FB Automatisierung und Informatik [email protected] Raum 2.202 Tel. 03943 / 659 338 Fachbereich Automatisierung und Informatik: BS, Java Native Interface 1 •Gliederung 1. 2. 3. 4. 5. 6. 7. Einführung Prozesse und Threads Speicherverwaltung Dateiverwaltung JNI STL Deadlocks Fachbereich Automatisierung und Informatik: BS, Java Native Interface 2 Java native Interface Gliederung 1 Einleitung 2 Möglichkeiten der Einbindung von Hardwareressourcen 3 Java Native Interface 4 Beispiele 5 Einbindung eines Mathematikprogramms in Java mittels JNI Fachbereich Automatisierung und Informatik: BS, Java Native Interface 3 1) Einleitung Programmiersprachen Eigenschaften einer Programmiersprache Syntax Ebene (Maschinennah, Compiler, Interpreter) Portierbarkeit Sprachumfang (Assembler, Fortran, OOP) Besondere Eigenschaften – – – Parallelprogrammierung Integration von Assembler Mehrfachvererbung Fachbereich Automatisierung und Informatik: BS, Java Native Interface 4 Interpreter / Compiler Sprachen Programmiersprachen Ein Compiler erzeugt nativen Code für eine ausgewählte Maschine. Portierbarkeit ? Ein Interpreter ist auf jeder Maschine lauffähig !? Portierbarkeit ? Fachbereich Automatisierung und Informatik: BS, Java Native Interface 5 Vorhandene Computersprachen Programmiersprachen Compiler: Assembler C / C++ D Cobol Fortran Modula Pascal Delphi Interpreter: Basic, VB.Net C# Java Lisp Perl Python Tcl VB Script Scala F# Fachbereich Automatisierung und Informatik: BS, Java Native Interface 6 2) Möglichkeitender der Einbindung von von 2. Möglichkeiten Einbindung Hardwareressourcen Hardwareressourcen Aufruf eines Programms. – – Kommunikation mittels Parameter und Dateien Kommunikation mittels Parameter und Pipes Einbindung von nativen Code in Java – Remote Method Invocation (RMI) Verteilte Javasysteme Aufruf externer Java Virtual Maschine RMI uses object serialization Fachbereich Automatisierung und Informatik: BS, Java Native Interface 7 Einbindung von nativender CodeEinbindung von 2. Möglichkeiten Hardwareressourcen Java Native Interface (JNI) – Anbindung über eine DLL – Java Intelligent Network Infrastructure (JINI) Java-basierende Technologie, erlaubt "spontanes Networking" der Geräte (CISCO) Jini soll regeln, wie Computer und andere Geräte sich miteinander im Netzwerk unterhalten. – Common Object Request Broker Architecture (CORBA) CORBA specifies a system which provides interoperability between objects in a heterogeneous, distributed environment and in a way transparent to the programmer. Its design is based on OMG Object Model. Fachbereich Automatisierung und Informatik: BS, Java Native Interface 8 3) Java Native Interface Allgemeines Das Java Native Interface ist eine sehr leistungsfähige Schnittstelle, um nativen Code einzubinden. Der native Code wird in eine DLL gekapselt. Die Kommunikation zwischen der Javaklasse und dem nativen Code erfolgt über das JNI. Folgende Sprachen können über eine DLL angesprochen werden: – – – – – – Assembler C / C++ / C# Cobol Delphi Fortran ( Visual Basic ) Fachbereich Automatisierung und Informatik: BS, Java Native Interface 9 Möglichkeiten des Java Native Interface Aufruf von Funktionen des nativen Codes Übergabe von Parametern – – – – Skalare Parameter (String, char, int, long, float, double, boolean) Arrays Strukturen Klassen Thread Exception Verwaltung Aufruf von statischen und dynamischen Methoden Adressierung von Feldern Referenzierung von Objekten und Objektoperationen Fachbereich Automatisierung und Informatik: BS, Java Native Interface 10 Vorteile von Java Native Interface Native Code Zugriff zum Betriebssystem Kopplung an andere Sprache (existierender Source) Kopplung an eine native Sprache – GUI mit Java – Algorithmus in C++ etc. Fachbereich Automatisierung und Informatik: BS, Java Native Interface 11 Nachteile von Java Native Interface Mindestens zwei Sprachen Neues Interface Debugging schwieriger DLL für jedes Betriebsystem – DLL Konzept überall gültig ? Fachbereich Automatisierung und Informatik: BS, Java Native Interface 12 Parameter des Java Native Interface Signature Z B C S I J F D LvollAdressierteKlasse; [ type ( arg-types) Returntyp V Java Typ boolean byte char short int long float double VollAdressierteKlasse Type [] Returntyp void Fachbereich Automatisierung und Informatik: BS, Java Native Interface 13 Grafischer Überblick: Dynamic Link Library Java Virtual Machine Java MainFrame Class JNIMathDLL Mathematik JNI Input C++ Output Fachbereich Automatisierung und Informatik: BS, Java Native Interface 14 Ablauf der einzelnen Schritte zur Entwicklung einer DLL Java Klasse / Programm erzeugen Deklaration der nativen Methode Kompilieren der Javadatei (javac) Erzeugen der Headerdatei (javah) Frame für eine DLL erzeugen (Visual Studio, BC++, g++) Header einbinden Prozedur einfügen DLL übersetzen (cl oder F7) Java-Programm starten (java) Fachbereich Automatisierung und Informatik: BS, Java Native Interface 15 Grafischer Überblick der Erzeugung javac Java Source javah Java Class cl DLL Source DLL java Fachbereich Automatisierung und Informatik: BS, Java Native Interface 16 Beispiele 4. Ein einfaches Beispiel 1. Beispiel: Aufruf einer Methode in einer DLL a) Erstellen des Java Codes (Bsp1.java) public class Bsp1 { // native method in the DLL public native void displayHelloHSHarz(); static { System.loadLibrary("dll1"); // dll1.dll } public static void main(String[] args) { Bsp1 app = new Bsp1(); app.displayHelloHSHarz(); System.out.println("Hier in Java"); } } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 17 b) Erstellen der Java-Class-Datei (Bsp1.java) Aufruf auf DOS-Ebene: javac Bsp1.java Erstellt die Datei java.class Fachbereich Automatisierung und Informatik: BS, Java Native Interface 18 c) Erstellen der Headerdatei aus Bsp1.class Aufruf auf DOS-Ebene: javah -jni Bsp1 Erstellt aus der Datei Bsp1.class die Datei Bsp1.h Fachbereich Automatisierung und Informatik: BS, Java Native Interface 19 Anzeige der Headerdatei Bsp1.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Example1 */ #ifndef _Included_Example1 #define _Included_Example1 #ifdef __cplusplus extern "C" { #endif /* * Class: Example1 * Method: displayHelloHSHarz * Signature: ()V */ JNIEXPORT void JNICALL Java_Bsp1_displayHelloHSHarz (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif Fachbereich Automatisierung und Informatik: BS, Java Native Interface 20 d) Erstellen der „Win 32 Dynamik Link Library“ mit Visual Studio 2010 ■ ■ ■ Visual Studio starten Menü File Eintrag New Eintrag Project Füllen des Dialogs Fachbereich Automatisierung und Informatik: BS, Java Native Interface 21 „Win 32 Dynamik Link Library“ Projekt erstellen Fachbereich Automatisierung und Informatik: BS, Java Native Interface 22 Fachbereich Automatisierung und Informatik: BS, Java Native Interface 23 Fachbereich Automatisierung und Informatik: BS, Java Native Interface 24 Fachbereich Automatisierung und Informatik: BS, Java Native Interface 25 Arbeitsablauf : Java-Code schreiben Native Methode definieren Übersetzen (javac) Erzeugen der Header-Datei (javah -jni test) Erzeugen einer DLL mittels Wizard Kopieren der Java-Headerdatei Kopieren der jni.h, jni_md.h Ändern des Eintrags in der Headerdatei •<jni.h> in "jni.h" Kopieren der Headerdateien in Source-Dir (drei Dateien) jni.h und jni_md.h und Bsp1.h Ersetzen der <jni.h> durch "jni.h" in Bsp1.h Einfügen des Source-Code (Methodenrumpf aus Bsp1.h kopieren) Einfügen des Import der Java-Headerdatei: #include "Bsp1.h" Übersetzen der DLL (F7) Kopieren der DLL ins Java-Verzeichnis Fachbereich Automatisierung und Informatik: BS, Java Native Interface 26 Erstellen der Prozedur für die Java Klasse in der DLL Übersetzen und linken der DLL „dll1.dll“ #include "stdafx.h" #include "Bsp1.h" JNIEXPORT void JNICALL Java_Bsp1_displayHelloHSHarz(JNIEnv *env, jobject obj) { puts("hallo HS Harz"); } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 27 Ausführen des Javaprogramms DOS-Ebene oder Eclipse C:\HSHarz>java Example1↵ Hier aus Microsoft DLL: Hallo HS Harz C:\HSHarz> Fachbereich Automatisierung und Informatik: BS, Java Native Interface 28 2. Beispiel: Aufruf einer Berechnung in der DLL Erstellen des Java Codes (Bsp2.java) public class Bsp2 { // native method in the DLL public native double callCalc(double a, double b); static { System.loadLibrary("dll2"); } public static void main(String[] args) { Bsp2 app = new Bsp2(); double d = app.callCalc(13,5); System.out.println("d: "+d); } } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 29 Erstellen der Headerdatei aus Example3.class Aufruf auf DOS-Ebene: javah -jni Bsp2 Erstellt aus der Datei Bsp2.class die Datei Bsp2.h Fachbereich Automatisierung und Informatik: BS, Java Native Interface 30 Anzeige der Headerdatei Bsp2.h #include "jni.h" /* Header for class Bsp2 */ #ifndef _Included_Bsp2 #define _Included_Bsp2 #ifdef __cplusplus extern "C" { #endif /* * Class: Bsp2 * Method: callCalc * Signature: (DD)D */ JNIEXPORT jdouble JNICALL Java_Bsp2_callCalc (JNIEnv *, jobject, jdouble, jdouble); #ifdef __cplusplus } #endif #endif Fachbereich Automatisierung und Informatik: BS, Java Native Interface 31 Erstellen der DLL mit der Prozedur für die Java Klasse #include "stdafx.h" // Neu #include „Bsp2.h" JNIEXPORT jdouble JNICALL Java_Bsp2_callCalc (JNIEnv *env, jobject obj, jdouble a, jdouble b) { return a+b; // Funktionscode } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 32 4. Beispiel: Aufruf einer Java-Methode aus der DLL Erstellen einer Wertetabelle Bsp4.java public class Bsp4 { public native void callWerteTabelle(double xa, double xsw, double xe); public void printXY(double x, double y) { System.err.println(" Java: x:"+x+"\ty:"+y); } public void start() { callWerteTabelle(1.0, 0.5, 10.0); } static { System.loadLibrary("dll4"); } public static void main(String[] args) { Bsp4 app = new Bsp4(); app.start(); app.pause(); } } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 33 #include "jni.h" /* Header for class Bsp4 */ #ifndef _Included_Bsp4 #define _Included_Bsp4 #ifdef __cplusplus extern "C" { #endif /* * Class: Bsp4 * Method: callWerteTabelle * Signature: (DDD)V */ JNIEXPORT void JNICALL Java_Bsp4_callWerteTabelle (JNIEnv *, jobject, jdouble, jdouble, jdouble); #ifdef __cplusplus } #endif Fachbereich Automatisierung und Informatik: BS, Java Native Interface #endif 34 #include "stdafx.h" #include "Bsp4.h" double fx(double x) { return x*x*x*x - 3.89*x*x*x + 5.66*x*x -3.6511*x + 0.8811; } // Funktion erstellt eine Wertetabelle // Anfangswert: xa // Schrittweite: xsw // Endewert: xe JNIEXPORT void JNICALL Java_Bsp4_callWerteTabelle (JNIEnv *env, jobject obj, jdouble xa, jdouble xsw, jdouble xe) { } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 35 JNIEXPORT void JNICALL Java_Bsp4_callWerteTabelle (JNIEnv *env, jobject obj, jdouble xa, jdouble xsw, jdouble xe) { // Pointer to a java method jmethodID method_printXY; // Pointer to a java class jclass clss; double x, y; // Hilfsvariablen // get the class clss = env->GetObjectClass(obj); method_printXY = env->GetMethodID(clss,"printXY", "(DD)V"); if (method_printXY==NULL) { puts("ERROR beim Referenzieren der Methode print_xy"); return; } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 36 // Schleife für die Wertetabelle x=xa; // Anfangswert while (x<=xe) { // Funktionswert holen y = fx(x); // Aufruf der Java-Methode env->CallVoidMethod(obj, method_printXY, x,y); // X-Wert erhöhen x+=xsw; }; puts("Ende der Berechnung"); } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 37 6. Beispiel: Benchmark Java vs. C-DLL private void callPrimzahlenJava(long max) { int i, j, n, k; double d; boolean bGefunden; for (i=2; i<max; i++) { d = i; n = (int) Math.sqrt(d)+1; bGefunden=true; for (j=2; j<=n; j++) { // d = Math.sin(44.0); k=i / j; // 10 div 2 ganzzahlig, oder modulo if ( (k*j) == i ) { // keine Primzahl bGefunden=false; break; } } } // for i } // callPrimzahlenJava Fachbereich Automatisierung und Informatik: BS, Java Native Interface 38 6. Beispiel: Benchmark Java vs. C-DLL public native void callPrimzahlenDLL(long max); static { System.loadLibrary("dll6"); } public static void main(String[] args) { Bsp6 frame = new Bsp6(); frame.setVisible(true); } } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 39 Zusammenfassung der JNI Lösung Standardisiert, portierbar Anpassung für jede Umgebung Ansprechen spezieller Betriebssystemfunktionen Ansprechen spezieller Hardware Benutzung von „non Java Code“ Benutzung von Java Code Zeitkritischer Code kann ausgelagert werden Echte Kommunikation des Javaprogramms mit zeitkritischem Code ist durch den Interpreter nicht immer gewährleistet (Java-Compiler bzw. Garbage-Collection). Mit "Just in Time" aber stark verbessert Fachbereich Automatisierung und Informatik: BS, Java Native Interface 40 Übergabe eines ArraysStatikprogramms an eine DLL 5.4)Einbindung eines class Example4 { inpublic Java mittels JNI private int [] array = new int[4]; public native void displayArray(int[] a); static { System.loadLibrary("Example4"); // Example4.dll } public Example4 () { for (int i=0; i<4; i++) array[i] = i+22; } public static void main(String[] args) { Example4 app = new Example4(); app.displayArray(app.array); pause(); } } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 41 DLL-Source-Code 5. Einbindung eines Statikprogramms void JNICALL JNI Java_Example4_displayArray(JNIEnv *env, inJNIEXPORT Java mittels jobject obj, jintArray intArray) { int i, k, n; // Bestimme die Länge des Feldes jsize len = env->GetArrayLength(intArray); // Array-Objekt holen jint *intArray0 = env->GetIntArrayElements(intArray,0); n = (int) len; printf("size: %d\n",n); for (i=0; i<n; i++) { k =intArray0[i]; printf("Array[ %d ] = %d\n",i,k); } } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 42 Performance-Vergleich Java /JNI 5.5)Einbindung eines Statikprogramms inAufgabe: Java mittels JNI • Zeitvergleich einer Java-Lösung und dem Aufruf einer Methode aus einer DLL. • Die Methoden berechnen die Primzahlen von 1 bis 1000. Fachbereich Automatisierung und Informatik: BS, Java Native Interface 43 5. Beispiel: Java-Code public class Bsp6 { private void callPrimzahlenJava() { // SourceCode } public native void callPrimzahlenDLL(); static { System.loadLibrary(“dll6"); } public static void main(String[] args) { Bsp6 app = new Bsp6(); app.callPrimzahlenJava(); app.callPrimzahlenDLL(); } } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 44 private void callPrimzahlenJava() { long t1, t2; int i, j, n, k; boolean bGefunden; t1 = System.currentTimeMillis(); for (i=2; i<100000; i++) { d = i; n = (int) Math.sqrt(d); bGefunden=true; for (j=2; j<=n; j++) { k=i / j; // 10 div 2 ganzzahlig if ( (k*j) == i ) { // keine Primzahl bGefunden=false; break; } } if (bGefunden) { System.out.println(i); } } // for i double d; t2 = System.currentTimeMillis(); } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 45 Anzeige der Headerdatei Bsp6.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Bsp6 */ #ifndef _Included_Bsp6 #define _Included_Bsp6 #ifdef __cplusplus extern "C" { #endif /* * Class: Bsp6 * Method: callPrimzahlenDLL * Signature: (J)V */ JNIEXPORT void JNICALL Java_Bsp6_callPrimzahlenDLL JNIEnv *, jobject, jlong); #ifdef __cplusplus } #endif #endif Fachbereich Automatisierung und Informatik: BS, Java Native Interface 46 Quellcode in der DLL // dll6.cpp : Definiert den Einsprungpunkt für die DLL-Anwendung. // #include "stdafx.h" #include "Bsp6.h" #include <math.h> #include <time.h> BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { return TRUE; } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 47 Quellcode in der DLL JNIEXPORT void JNICALL Java_Bsp6_callPrimzahlenDLL (JNIEnv *env, jobject obj, jlong max) { int i, j, n, k; double d; BOOL bGefunden; for (i=2; i<max; i++) { d = i; n = (int) sqrt(d); bGefunden=true; for (j=2; j<=n; j++) { k=i / j; // 10 div 2 ganzzahlig if ( (k*j) == i ) { // keine Primzahl bGefunden=false; break; } } if (bGefunden) { printf("%u\n",i); } } // for i } Fachbereich Automatisierung und Informatik: BS, Java Native Interface 48 Zeitvergleich: Dual Core, 2,53 GHz Anzahl Java-Zeit [ms] 100 000 16 1000 000 296 10 000 000 7160 100 000 000 192676 1 000 000 000 C-DLL Zeit [ms] 16 296 7364 195921 Faktor 1,0 1,0 1,0 Ohne Ausgabe der Primzahlen: JDK 1,6 Fachbereich Automatisierung und Informatik: BS, Java Native Interface 49 Einbindung eineseines Mathematikprogramms in 5. Einbindung Statikprogramms in Java mittelsJava JNImittels JNI Problem: Ein existierendes Fortranprogramm, 20 Jahre alt, kommerziell genutzt, soll über einem in Java geschriebenen Mainframe angesteuert werden. Die errechneten Daten sollen während der Berechnung an das Javaprogramm übermittelt werden und dort in Listen und Grafiken angezeigt werden. Das Mainframe soll in einem modernen Programmstil erstellt werden. Model View Concept Lokalisierung der Sprache Look & Feel Unterstützung Automatische Generierung der Dialogfenster Grafische Anzeige der aktuell errechneten Daten Fachbereich Automatisierung und Informatik: BS, Java Native Interface 50 Grafischer Aufbau Grafischer Aufbau Dynamic Link Library Java Virtual Machine Java MainFrame Class JNIMathDLL Fortran Mathematikprogramm JNI Input C++ Output Fachbereich Automatisierung und Informatik: BS, Java Native Interface 51