Applicazioni native in java

  • 4,732 views
Uploaded on

java applicazioni native

java applicazioni native

More in: Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
4,732
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
126
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

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