Suggerimento Java 23: scrivi metodi nativi

La capacità di scrivere un solo set di codice in Java e di eseguirlo su ogni sistema con runtime Java è uno dei principali punti di forza di Java. Ma questa indipendenza dalla piattaforma ha uno svantaggio fondamentale: cosa facciamo con la grande quantità di codice esistente? Il trucco sta nell'usare la cosiddetta interfaccia del metodo nativo .

La scrittura di metodi nativi implica l'importazione di codice C nell'applicazione Java. In questo suggerimento ti guiderò attraverso la ricetta di base per creare metodi nativi e utilizzarli in un'applicazione Java.

Sette passaggi per il nirvana del metodo nativo I passaggi per la creazione di metodi nativi sono i seguenti:

  • Scrivi codice Java
  • Compila il codice Java
  • Crea intestazione C ( file .h )
  • Crea file stub C.
  • Scrivi il codice C.
  • Crea libreria di codici condivisi (o DLL)
  • Esegui l'applicazione

Il nostro esercizio consiste nello scrivere del testo nella console dall'interno del metodo nativo. Le specifiche di questo esempio saranno orientate verso un sistema simile a Unix, in particolare Linux. Segnalerò i due punti in cui i dettagli differiscono per altre piattaforme.

Scrivi codice Java

Scrivi il tuo codice Java come faresti normalmente. Per utilizzare metodi nativi nel codice Java, è necessario eseguire due operazioni. Innanzitutto, scrivi una dichiarazione di metodo nativo per ogni metodo nativo che desideri utilizzare. È proprio come scrivere la dichiarazione di una normale interfaccia del metodo Java, ma è necessario specificare la parola chiave native , come segue:

public native void printText (); 

Il secondo telaio da superare è che devi caricare esplicitamente la libreria del codice nativo. (Lo creeremo più tardi.) Lo facciamo caricando la libreria in un blocco statico di classe:

static {System.loadLibrary ("happy"); }

Per mettere insieme questi pezzi per il nostro esempio, crea un file chiamato Happy.javacon il seguente contenuto:

class Happy {public native void printText (); static {System.loadLibrary ("happy"); / * Nota il nome della classe in minuscolo! * /} public static void main (String [] args) {Happy happy = new Happy (); happy.printText (); }}

Compila il codice Java

Compila il Happy.javafile:

% javac Happy.java 

Crea un file di intestazione C.

Ci sono vari incantesimi magici che devono essere resi disponibili in modo che il nostro codice C possa essere utilizzato come metodo nativo. La javahfunzionalità del compilatore Java genererà le dichiarazioni necessarie e simili dalla nostra Happyclasse. Questo creerà un Happy.hfile da includere nel nostro codice C:

% javah Happy 

Crea un file di stub C.

In un modo che ricorda il mangling che i traduttori C ++ fanno ai nomi dei metodi C ++, il compilatore Java ha una follia simile. Per alleviare il dolore di dover scrivere un sacco di codice noioso in modo che il nostro codice C possa essere richiamato dal sistema run-time Java, il compilatore Java può generare automaticamente il codice trampolino necessario:

% javah -stubs Happy 

Scrivi il codice C.

Ora scriviamo il codice vero e proprio per stampare il nostro saluto. Per convenzione mettiamo questo codice in un file chiamato dopo la nostra classe Java con la stringa "Imp" aggiunta ad esso. Ciò si traduce in HappyImp.c. Inserisci quanto segue in HappyImp.c:

#include & ltStubPreamble.h> / * Roba del metodo nativo standard. * / #include "Happy.h" / * Generato in precedenza. * / #include & ltstdio.h> / * Roba standard C IO. * / void Happy_printText (struct HHappy * this) {put ("Happy New Year !!!"); }

Nell'interfacciare il codice C con Java, sono coinvolti molti altri aspetti, ad esempio come passare e restituire la miriade di tipi. Per ulteriori informazioni, vedere il tutorial Java o l'Hermetica Native Methods Paper (vedere la sezione Risorse per gli URL).

Crea una libreria condivisa

This section is the most system-dependent. It seems like every platform and each compiler/linker combination has a different method of creating and using shared libraries. For folks using any of the various Microsoft Windows platforms, check the documentation for your C compiler for the nitty-gritty details.

For you Linux folks, here's how to create a shared library using GCC. First, compile the C source files that we have already created. You have to tell the compiler where to find the Java native method support files, but the main trick here is that you have to explicitly tell the compiler to produce Position Independent Code:

% gcc -I/usr/local/java/include -I/usr/local/java/include/genunix -fPIC -c Happy.c HappyImp.c 

Ora, crea una libreria condivisa dai file oggetto (.o) risultanti con il seguente incantesimo magico:

% gcc -shared -Wl, -soname, libhappy.so.1 -o libhappy.so.1.0 Happy.o HappyImp.o 

Copiare il file della libreria condivisa nel nome breve standard:

% cp libhappy.so.1.0 libhappy.so 

Infine, potrebbe essere necessario indicare al linker dinamico dove trovare questo nuovo file di libreria condivisa. Utilizzando la shell bash :

% export LD_LIBRARY_PATH = `pwd`: $ LD_LIBRARY_PATH 

Esegui l'applicazione

Esegui l'applicazione Java come al solito:

% java Happy 

Bene, questo è tutto quello che c'è da fare. Grazie a Tony Dering per aver trasmesso gli incantesimi specifici per Linux.

Una rapida nota di progettazione

Prima di affrettarmi a scrivere metodi nativi per tutto quel codice legacy, vorrei avvertire tutti noi di guardare attentamente i sistemi esistenti e vedere se ci sono modi migliori per collegarli a Java. Ad esempio, esistono Java Database Connectivity (JDBC) e anche soluzioni di livello superiore per l'accesso ai database da Java. Quindi, guarda tutti i trucchi nella tua borsa e usa ciò che ha senso per il progetto in questione.

Ulteriori informazioni su questo argomento

  • JavaSoft Native Method Tuturial //www.javasoft.com/books/Series/Tutorial/native/implementing/index.html
  • Hermetica Native Methods Paper //www.hermetica.com/technologia/java/native/

Questa storia, "Java Tip 23: Scrivi metodi nativi" è stata originariamente pubblicata da JavaWorld.