23
J2EE Training: http://courses.coreservlets.com/ Servlets, JSP, Struts, JSF, Hibernate, AJAX, Java 5, etc. Developed and taught by well-known author and developer. At public venues or onsite at your location. © 2006 Marty Hall 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

Applicazioni native in java

Embed Size (px)

DESCRIPTION

java applicazioni native

Citation preview

Page 1: Applicazioni native in java

J2EE Training: http://courses.coreservlets.com/Servlets, JSP, Struts, JSF, Hibernate, AJAX, Java 5, etc.

Developed and taught by well-known author and developer. At public venues or onsite at your location.

© 2006 Marty Hall

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

Page 2: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Agenda

• Opzioni di integrazione• Eseguire applicazioni native• Invocare funzioni native

Page 3: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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

Page 4: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Invocazione di applicazioni Native

1. 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.

2. 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();

Page 5: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Esempio: Lanciare Internet Explorer

• Path completo di Internet Explorer:– C:\Programmi\Internet Explorer\iexplore.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

Page 6: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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:\\Programmi\\Internet Explorer\\iexplore", url); builder.start(); } catch(Exception e) { System.out.println(e); } }}

Page 7: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Esempio: risultati

DOS> java InvokeIE http://www.javastaff.com/

Page 8: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Leggere i risultati di un’applicazione nativa

1. Istanziare un ProcessBuilder– ProcessBuilder builder =

new ProcessBuilder("program", "argument");2. Avviare il processo

– Process p = builder.start();3. Utilizzare un Reader (come input, non

come output!)– BufferedReader reader =

new BufferedReader (new InputStreamReader (p.getInputStream()));

4. Leggere i risultati– Chiamare reader.readLine() finchè il risultato non è null

5. Chiudere lo stream– reader.close();

Page 9: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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();

Page 10: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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); } }}

Page 11: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Esempio: Invocare il comando Unix “ls” (Risultati indentati)Unix> java InvokeLSOutput: total 12Output: 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.classOutput: -rw-r--r-- 1 hall instruct 846 Nov 26 10:00 InvokeLS.java

Page 12: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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

Page 13: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Utilizzare Metodi Nativi

1. Creare classi Java con metodi nativi– Metodi stub dichiarati native– Caricare le librerie shared utilizzando System.loadLibrary

2. Compilare il codice Java – Utilizzare normalmente javac

3. Creare un header per la classe Java– Usando "javah -jni ClassName"

4. Scrivere un programma C con le funzioni progettate– includere ClassName.h and jni.h

5. Compilare l’applicazione C come shared library– Includere come path must javahome/include e javahome/include/operatingsystem

6. Lanciare il programma Java– Utilizzando normalmente java

Page 14: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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(); }}

Page 15: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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 __cplusplusextern "C" {#endif...JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);...

Page 16: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Scrivere il programma C

#include <jni.h>#include "HelloWorld.h"#include <stdio.h>

JNIEXPORT void JNICALLJava_HelloWorld_displayHelloWorld (JNIEnv *env, jobject obj){ printf("Hello world!\n"); return;}

Page 17: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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

Page 18: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Invocare il programma Java

Solaris> java HelloWorldHello world!

Page 19: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

Mappatura dei tipi Java in tipi C (Primitive)

Java Type Native Type Size in Bits

boolean jboolean 8, unsigned

byte jbyte 8

char jchar 16, unsigned

short jshort 16

int jint 32

long jlong 64

float jfloat 32

double jdouble 64

void void

Page 20: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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

Page 21: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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, "callback", "(I)V"); if (mid == 0) { return; } printf("In C, depth = %d, about to enter Java\n", depth); (*env)->CallVoidMethod(env, obj, mid, depth); printf("In C, depth = %d, back from Java\n", depth); }

Page 22: Applicazioni native in java

J2EE training: http://courses.coreservlets.com

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.

Page 23: Applicazioni native in java

J2EE Training: http://courses.coreservlets.com/Servlets, JSP, Struts, JSF, Hibernate, AJAX, Java 5, etc.

Developed and taught by well-known author and developer. At public venues or onsite at your location.

© 2006 Marty Hall

Domande?Visitate il forum di

http://www.javastaff.comse avete dubbi.