Invocare Applicazioni Native in Java Slides Originali e codice d’esempio: http://courses.coreservlets.com/Course-Materials...
Agenda <ul><li>Opzioni di integrazione </li></ul><ul><li>Eseguire applicazioni native </li></ul><ul><li>Invocare funzioni ...
Collegamento a programmi in altri Linguaggi <ul><li>Invocare i programmi al livello OS </li></ul><ul><ul><li>Usare Process...
Invocazione di applicazioni Native <ul><li>Creare un ProcessBuilder </li></ul><ul><ul><li>ProcessBuilder builder =    new ...
Esempio: Lanciare Internet Explorer <ul><li>Path completo di Internet Explorer: </li></ul><ul><ul><li>C:ProgrammiInternet ...
Esempio: Codice <ul><li>public class InvokeIE { </li></ul><ul><li>public static void main(String[] args) { </li></ul><ul><...
Esempio: risultati <ul><li>DOS> java InvokeIE http://www.javastaff.com/ </li></ul>
Leggere i risultati di un’applicazione nativa <ul><li>Istanziare un ProcessBuilder </li></ul><ul><ul><li>ProcessBuilder bu...
Esempio: Invocare il comando Unix “ls” <ul><li>import java.io.*; </li></ul><ul><li>public class InvokeLS { </li></ul><ul><...
Esempio: Invocare il comando Unix “ls” <ul><li>BufferedReader reader = </li></ul><ul><li>new BufferedReader </li></ul><ul>...
Esempio: Invocare il comando Unix “ls” (Risultati indentati) <ul><li>Unix> java InvokeLS </li></ul><ul><li>Output: total 1...
Invocare Metodi Nativi <ul><li>E’ possibile chiamare funzioni  C da Java </li></ul><ul><ul><li>Le funzioni C++ devono esse...
Utilizzare Metodi Nativi <ul><li>Creare classi Java con metodi nativi </li></ul><ul><ul><li>Metodi stub dichiarati  native...
Creare Classi Java <ul><li>Bisogna usare la dichiarazione native </li></ul><ul><li>Must caricare le librerie shared prima ...
Creare un File Header <ul><li>> javac HelloWorld.java </li></ul><ul><li>> javah -jni HelloWorld </li></ul><ul><ul><li>Resu...
Scrivere il programma C <ul><li>#include <jni.h> </li></ul><ul><li>#include &quot;HelloWorld.h&quot; </li></ul><ul><li>#in...
Compilare il programma C come libreria Shared <ul><li>Bisogna includere i file .h files per JNI </li></ul><ul><ul><li>Gene...
Invocare il programma Java <ul><li>Solaris> java HelloWorld </li></ul><ul><li>Hello world! </li></ul>
Mappatura dei tipi Java in tipi C  (Primitive) void void 64 jdouble double 32 jfloat float 64 jlong long 32 jint int 16 js...
Mappatura di Oggetti Java in C <ul><li>Tutte le chiamate sono fatte per riferimento </li></ul><ul><li>Tutti gli oggetti so...
Chiamare Metodi Java da C <ul><li>Chiamare la funzione GetObjectClass  </li></ul><ul><li>Chiamare GetMethodID </li></ul><u...
Ricapitolando <ul><li>Invocare applicazioni del sistema operativo </li></ul><ul><ul><li>Utilizzare ProcessBuilder.start() ...
Domande? Visitate il forum di http://www.javastaff.com se avete dubbi.
Upcoming SlideShare
Loading in …5
×

Applicazioni native in java

5,122 views

Published on

java applicazioni native

Published in: Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,122
On SlideShare
0
From Embeds
0
Number of Embeds
105
Actions
Shares
0
Downloads
129
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Applicazioni native in java

  1. 1. Invocare Applicazioni Native in Java Slides Originali e codice d’esempio: http://courses.coreservlets.com/Course-Materials/java5.html Traduzione a cura di: http://www.javastaff.com
  2. 2. Agenda <ul><li>Opzioni di integrazione </li></ul><ul><li>Eseguire applicazioni native </li></ul><ul><li>Invocare funzioni native </li></ul>
  3. 3. Collegamento a programmi in altri Linguaggi <ul><li>Invocare i programmi al livello OS </li></ul><ul><ul><li>Usare ProcessBuilder per invocare un programma scelto a caso, passando argomenti presi dallo standard input, e leggere i risultati dallo standard output </li></ul></ul><ul><ul><ul><li>Pro: facile da utilizzare, puo’ invocare qualsiasi applicazione. </li></ul></ul></ul><ul><ul><ul><li>Contro: numero limitato di argomenti da passare, lento: overhead all’avvio considerevole. </li></ul></ul></ul><ul><li>Utilizzare le socket </li></ul><ul><ul><li>Utilizzare le socket per scambiare dati </li></ul></ul><ul><ul><ul><li>Pro: veloce in locale, possibilità di distribuire le componenti su piu’ macchine </li></ul></ul></ul><ul><ul><ul><li>Contro: set up laborioso, necessità di un protocollo di comunicazione e di un parsing dei dati </li></ul></ul></ul><ul><li>Utilizzare metodi nativi </li></ul><ul><ul><li>Utilizzare JNI per linkare codice C e Java </li></ul></ul><ul><ul><ul><li>Pro: veloce: utilizzabile per interazioni che richiedono particolare cura. </li></ul></ul></ul><ul><ul><ul><li>Contro: metodo molto laborioso, necessita conoscenze di C, C++ o assebly </li></ul></ul></ul>
  4. 4. Invocazione di applicazioni Native <ul><li>Creare un ProcessBuilder </li></ul><ul><ul><li>ProcessBuilder builder = new ProcessBuilder(&quot;program&quot;, &quot;argument&quot;); </li></ul></ul><ul><ul><li>Notare che le variabili di sistema non sono automaticamente settate (il PATH ad esempio), quindi va utilizzato il path completo. </li></ul></ul><ul><li>Lanciare il processo </li></ul><ul><ul><li>builder.start(); </li></ul></ul><ul><li>Opzioni </li></ul><ul><ul><li>Attendere che il processo termini (bloccante) </li></ul></ul><ul><ul><ul><li>Process p = builder.start(); </li></ul></ul></ul><ul><ul><ul><li>int returnCode = p.waitFor(); </li></ul></ul></ul><ul><ul><li>Esaminare i valori di ritorno successivamente (non bloccante) </li></ul></ul><ul><ul><ul><li>int returnCode = p.exitCode(); </li></ul></ul></ul>
  5. 5. Esempio: Lanciare Internet Explorer <ul><li>Path completo di Internet Explorer: </li></ul><ul><ul><li>C:ProgrammiInternet Exploreriexplore.exe </li></ul></ul><ul><ul><ul><li>In Java bisogna utilizzare per indicare </li></ul></ul></ul><ul><ul><ul><li>L’estensione .exe puo’ essere omessa in Windows </li></ul></ul></ul><ul><li>Internet Explorer accetta parametri da riga di comando </li></ul><ul><ul><li>URL iniziale da mostrare </li></ul></ul><ul><ul><ul><li>Sovrascrive l’homepage </li></ul></ul></ul>
  6. 6. Esempio: Codice <ul><li>public class InvokeIE { </li></ul><ul><li>public static void main(String[] args) { </li></ul><ul><li>String url = &quot;http://www.javastaff.com/&quot;; </li></ul><ul><li>if (args.length > 0) { </li></ul><ul><li>url = args[0]; </li></ul><ul><li>} </li></ul><ul><li>try { </li></ul><ul><li>ProcessBuilder builder = </li></ul><ul><li>new ProcessBuilder( </li></ul><ul><li>&quot;C:rogramminternet Explorerexplore&quot;, </li></ul><ul><li>url); </li></ul><ul><li>builder.start(); </li></ul><ul><li>} catch(Exception e) { </li></ul><ul><li>System.out.println(e); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  7. 7. Esempio: risultati <ul><li>DOS> java InvokeIE http://www.javastaff.com/ </li></ul>
  8. 8. Leggere i risultati di un’applicazione nativa <ul><li>Istanziare un ProcessBuilder </li></ul><ul><ul><li>ProcessBuilder builder = new ProcessBuilder(&quot;program&quot;, &quot;argument&quot;); </li></ul></ul><ul><li>Avviare il processo </li></ul><ul><ul><li>Process p = builder.start(); </li></ul></ul><ul><li>Utilizzare un Reader (come input, non come output!) </li></ul><ul><ul><li>BufferedReader reader = new BufferedReader (new InputStreamReader (p.get Input Stream())); </li></ul></ul><ul><li>Leggere i risultati </li></ul><ul><ul><li>Chiamare reader.readLine() finchè il risultato non è null </li></ul></ul><ul><li>Chiudere lo stream </li></ul><ul><ul><li>reader.close(); </li></ul></ul>
  9. 9. Esempio: Invocare il comando Unix “ls” <ul><li>import java.io.*; </li></ul><ul><li>public class InvokeLS { </li></ul><ul><li>public static void main(String[] args) { </li></ul><ul><li>String flags = &quot;-al&quot;; </li></ul><ul><li>if (args.length > 0) { </li></ul><ul><li>flags = args[0]; </li></ul><ul><li>} </li></ul><ul><li>try { </li></ul><ul><li>ProcessBuilder builder = </li></ul><ul><li>new ProcessBuilder(&quot;/usr/bin/ls&quot;, flags); </li></ul><ul><li>Process process = builder.start(); </li></ul>
  10. 10. Esempio: Invocare il comando Unix “ls” <ul><li>BufferedReader reader = </li></ul><ul><li>new BufferedReader </li></ul><ul><li>(new InputStreamReader </li></ul><ul><li>(process.getInputStream())); </li></ul><ul><li>String line; </li></ul><ul><li>while((line = reader.readLine() ) != null) { </li></ul><ul><li>System.out.printf(&quot;Output: %s%n&quot;, line); </li></ul><ul><li>} </li></ul><ul><li>reader.close(); </li></ul><ul><li>int status = process.exitValue(); </li></ul><ul><li>if (status != 0) { </li></ul><ul><li>System.out.printf(&quot;Error: process exited with %d.%n&quot;, </li></ul><ul><li>status); </li></ul><ul><li>} </li></ul><ul><li>} catch(Exception e) { </li></ul><ul><li>System.out.println(e); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  11. 11. Esempio: Invocare il comando Unix “ls” (Risultati indentati) <ul><li>Unix> java InvokeLS </li></ul><ul><li>Output: total 12 </li></ul><ul><li>Output: drwxr-xr-x 2 hall instruct </li></ul><ul><li>512 Nov 26 10:00 . </li></ul><ul><li>Output: drwxr-xr-x 6 hall instruct </li></ul><ul><li>2048 Nov 26 09:38 .. </li></ul><ul><li>Output: -rw-r--r-- 1 hall instruct </li></ul><ul><li>1257 Nov 26 10:00 InvokeLS.class </li></ul><ul><li>Output: -rw-r--r-- 1 hall instruct </li></ul><ul><li>846 Nov 26 10:00 InvokeLS.java </li></ul>
  12. 12. Invocare Metodi Nativi <ul><li>E’ possibile chiamare funzioni C da Java </li></ul><ul><ul><li>Le funzioni C++ devono essere dichiarate come &quot;extern C&quot; </li></ul></ul><ul><ul><li>Non si possono chiamare ad esempio funzioni FORTRAN, ma funzioni C possono facilmente (?) fungere da intermediari </li></ul></ul><ul><ul><ul><li>Vedi http://www.csharp.com/javacfort.html </li></ul></ul></ul><ul><li>Si puo’ anche invocare funzioni Java da applicazioni C </li></ul><ul><li>Molto piu’ laborioso </li></ul><ul><ul><li>Necessita noiosa programmazione a basso livello su entrambe le parti (Java e C) </li></ul></ul><ul><li>Molto piu’ potente </li></ul><ul><ul><li>Si possono passare tipi di dati reali (non solo stringhe) </li></ul></ul><ul><ul><li>Non si lancia un processo per il Sistema Operativo ad ogni chiamata </li></ul></ul><ul><li>Maggiori dettagli </li></ul><ul><ul><li>Generale: http://java.sun.com/docs/books/tutorial/native1.1/ </li></ul></ul><ul><ul><li>MATLAB: http://www.mathworks.com/access/helpdesk/help/techdoc/ matlab_external/f44062.html </li></ul></ul>
  13. 13. Utilizzare Metodi Nativi <ul><li>Creare classi Java con metodi nativi </li></ul><ul><ul><li>Metodi stub dichiarati native </li></ul></ul><ul><ul><li>Caricare le librerie shared utilizzando System.loadLibrary </li></ul></ul><ul><li>Compilare il codice Java </li></ul><ul><ul><li>Utilizzare normalmente javac </li></ul></ul><ul><li>Creare un header per la classe Java </li></ul><ul><ul><li>Usando &quot;javah -jni ClassName &quot; </li></ul></ul><ul><li>Scrivere un programma C con le funzioni progettate </li></ul><ul><ul><li>includere ClassName .h and jni.h </li></ul></ul><ul><li>Compilare l’applicazione C come shared library </li></ul><ul><ul><li>Includere come path must javahome /include e javahome /include/ operatingsystem </li></ul></ul><ul><li>Lanciare il programma Java </li></ul><ul><ul><li>Utilizzando normalmente java </li></ul></ul>
  14. 14. Creare Classi Java <ul><li>Bisogna usare la dichiarazione native </li></ul><ul><li>Must caricare le librerie shared prima di invocarne i metodi </li></ul><ul><li>public class HelloWorld { </li></ul><ul><li>static { </li></ul><ul><li>System.loadLibrary(&quot;hello&quot;); </li></ul><ul><li>} </li></ul><ul><li>public native void displayHelloWorld(); </li></ul><ul><li>public static void main(String[] args) { </li></ul><ul><li>new HelloWorld().displayHelloWorld(); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  15. 15. Creare un File Header <ul><li>> javac HelloWorld.java </li></ul><ul><li>> javah -jni HelloWorld </li></ul><ul><ul><li>Result: HelloWorld.h </li></ul></ul><ul><ul><li>/* DO NOT EDIT THIS FILE - it is machine generated */ </li></ul></ul><ul><ul><li>#include <jni.h> </li></ul></ul><ul><ul><li>/* Header for class HelloWorld */ </li></ul></ul><ul><ul><li>#ifndef _Included_HelloWorld </li></ul></ul><ul><ul><li>#define _Included_HelloWorld </li></ul></ul><ul><ul><li>#ifdef __cplusplus </li></ul></ul><ul><ul><li>extern &quot;C&quot; { </li></ul></ul><ul><ul><li>#endif </li></ul></ul><ul><ul><li>... </li></ul></ul><ul><ul><li>JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld </li></ul></ul><ul><ul><li>(JNIEnv *, jobject); </li></ul></ul><ul><ul><li>... </li></ul></ul>
  16. 16. Scrivere il programma C <ul><li>#include <jni.h> </li></ul><ul><li>#include &quot;HelloWorld.h&quot; </li></ul><ul><li>#include <stdio.h> </li></ul><ul><li>JNIEXPORT void JNICALL </li></ul><ul><li>Java_HelloWorld_displayHelloWorld </li></ul><ul><li>(JNIEnv *env, jobject obj) </li></ul><ul><li>{ </li></ul><ul><li>printf(&quot;Hello world! &quot;); </li></ul><ul><li>return; </li></ul><ul><li>} </li></ul>
  17. 17. Compilare il programma C come libreria Shared <ul><li>Bisogna includere i file .h files per JNI </li></ul><ul><ul><li>Generali </li></ul></ul><ul><ul><li>Specifici del OS utilizzato </li></ul></ul><ul><li>Solaris> gcc </li></ul><ul><li>-I/usr/java1.5/include </li></ul><ul><li>-I/usr/java1.5/include/solaris </li></ul><ul><li>HelloWorldImp.c </li></ul><ul><li>-o libhello.so </li></ul>
  18. 18. Invocare il programma Java <ul><li>Solaris> java HelloWorld </li></ul><ul><li>Hello world! </li></ul>
  19. 19. Mappatura dei tipi Java in tipi C (Primitive) void void 64 jdouble double 32 jfloat float 64 jlong long 32 jint int 16 jshort short 16, unsigned jchar char 8 jbyte byte 8, unsigned jboolean boolean Size in Bits Native Type Java Type
  20. 20. Mappatura di Oggetti Java in C <ul><li>Tutte le chiamate sono fatte per riferimento </li></ul><ul><li>Tutti gli oggetti sono jobject in C </li></ul><ul><li>Alcuni sottotipi di jobject predefiniti </li></ul><ul><ul><li>jstring </li></ul></ul><ul><ul><li>jintArray, jshortArray, jlongArray </li></ul></ul><ul><ul><li>jfloatArray, jdoubleArray </li></ul></ul><ul><ul><li>jcharArray </li></ul></ul><ul><ul><li>jbyteArray </li></ul></ul><ul><ul><li>jbooleanArray </li></ul></ul><ul><ul><li>jobjectArray </li></ul></ul>
  21. 21. Chiamare Metodi Java da C <ul><li>Chiamare la funzione GetObjectClass </li></ul><ul><li>Chiamare GetMethodID </li></ul><ul><li>Chiamare CallVoidMethod </li></ul><ul><li>JNIEXPORT void JNICALL </li></ul><ul><li>Java_Callbacks_nativeMethod(JNIEnv *env, jobject obj, </li></ul><ul><li>jint depth) { </li></ul><ul><li>jclass cls = (*env)->GetObjectClass(env, obj); </li></ul><ul><li>jmethodID mid = (*env)->GetMethodID(env, cls, </li></ul><ul><li>&quot;callback&quot;, &quot;(I)V&quot;); </li></ul><ul><li>if (mid == 0) { return; } </li></ul><ul><li>printf(&quot;In C, depth = %d, about to enter Java &quot;, </li></ul><ul><li>depth); </li></ul><ul><li>(*env)->CallVoidMethod(env, obj, mid, depth); </li></ul><ul><li>printf(&quot;In C, depth = %d, back from Java &quot;, depth); </li></ul><ul><li>} </li></ul>
  22. 22. Ricapitolando <ul><li>Invocare applicazioni del sistema operativo </li></ul><ul><ul><li>Utilizzare ProcessBuilder.start() per lanciare il programma con i parametri opzionali </li></ul></ul><ul><ul><li>E’ possibile leggere l’output </li></ul></ul><ul><ul><ul><li>Utilizzando un BufferedReader sull’input stream </li></ul></ul></ul><ul><li>Si possono utilizzare le socket per la comunicazione </li></ul><ul><ul><li>Vedere la letteratura precedente </li></ul></ul><ul><ul><li>Molto veloce se entrambe le applicazioni sono sulla stessa macchina </li></ul></ul><ul><li>JNI offre l’integrazione piu’ elegante e performante </li></ul><ul><ul><li>Implementazione noiosa e molto a basso livello. Manutenzione impegnativa. </li></ul></ul>
  23. 23. Domande? Visitate il forum di http://www.javastaff.com se avete dubbi.

×