Esempio di utilizzo di librerie condivise su z/OS

Questo esempio descrive il processo di utilizzo delle librerie condivise native con un'applicazione Java™ su sistemi z/OS.

Informazioni su questa attività

Questa attività mostra come creare un'applicazione Java che carichi e invochi funzioni C all'interno di una libreria condivisa nativa.

Procedura

  1. Creare un'applicazione di esempio 'Sample.java:
    public class Sample {
        /**
         * A static class initialization block that is run when this class
         * is first loaded. Here, try to load the target libSample.so shared library
         * that implements the printFromNative() method declared later.
         */
        static {
            try {
                System.loadLibrary("Sample");
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        }
        
        /**
         * Prints a message to STDOUT.
         * The 'native' keyword indicates that this method is implemented in native code,
         * callable through the Java Native Interface (JNI).
         */
        public static native void printFromNative();
    
        public static void main(String[] args) {
            // Invoke the native method
            Sample.printFromNative();
        }
    }

    Questa applicazione Java dichiara un metodo nativo statico " Sample.printFromNative() e lo chiama dal metodo " main.

    Durante il blocco di inizializzazione della classe statica che viene eseguito quando la classe 'Sample viene caricata per la prima volta, la chiamata 'System.loadLibrary("Sample") carica la libreria nativa di destinazione 'libSample.so.
    Nota: L'API 'System.loadLibrary(libname) aggiunge il prefisso 'lib e il suffisso '.so al nome della libreria fornito. L'SDK cerca la libreria condivisa di destinazione nel percorso della libreria specificato nella variabile d'ambiente 'LIBPATH. Se la libreria condivisa nativa di destinazione è un insieme di dati MVS o se si dispone di un percorso assoluto o di un nome di libreria specifico, utilizzare invece l'API 'System.load(filename).
  2. La parte Java dell'applicazione è completa, quindi è ora possibile compilarla:
    javac Sample.java
  3. Utilizzare il comando javac -h per creare un file di intestazione per il codice nativo:
    javac -h . Sample.java
    Questo comando genera un file di intestazione C, chiamato 'Sample.h, con le firme dei metodi JNI appropriate per l'implementazione dell'applicazione nativa.
  4. Crea un file denominato Sample.c:
    #include <stdio.h>
    #include "Sample.h"
    
    JNIEXPORT void JNICALL Java_Sample_printFromNative(JNIEnv * env, jclass cls) {
      printf( "Printing from native\n" );
    }
    Questo file fornisce l'implementazione nativa C del metodo Java Sample.printFromNative() .
  5. Compila 'Sample.c, lo collega e lo lega in una libreria condivisa 'libSample.so, che può essere caricata e richiamata dinamicamente da un'applicazione Java. È possibile utilizzare il compilatore XL C/C++ o Open XL C/C++.

    comando XL C/C++
    Ad esempio:
    xlc -q64 -W "l,dll" -W "c,langlvl(extended),float(ieee),dll,exportall" -o libSample.so -I$JAVA_HOME/include -I$JAVA_HOME/include/zos Sample.c $JAVA_HOME/lib/j9vm/libjvm.x

    dove '$JAVA_HOME è il percorso JAVA_HOME dell'installazione di IBM SDK. Il file di intestazione 'jni.h esiste sotto '$JAVA_HOME/include e 'libjvm.x è in '$JAVA_HOME/lib/ 'j9vm.

    Gli elementi specifici di 'XL C/C++ nei comandi di compilazione e collegamento sono i seguenti:
    Tabella 1. Elementi specifici del comando XL C/C++
    Opzione Descrizione
    xlc Il comando che esegue il compilatore C di XL.
    -q64 Opzione valida solo per i 64 bit. Indica al compilatore di compilare la libreria condivisa di destinazione per piattaforme AMODE64 .
    --W "l,dll" L'opzione -W viene passata alla fase di collegamento del compilatore. Il linker crea un file di libreria condivisa '.so.
    --W "c,langlvl(esteso),
    galleggiante(ieee),
    dll, exportall"
    L'opzione -W viene passata alla fase di compilazione del compilatore.
    • langlvl(extended) abilita le estensioni di linguaggio utilizzate dai file di intestazione JNI, come long long.
    • float(ieee) indica al compilatore di creare istruzioni e numeri a virgola mobile IEEE754 binari, che corrispondono ai tipi primitivi float e double del linguaggio Java.
    • dll indica al compilatore di produrre codice DLL. Il codice DLL può esportare o importare funzioni e variabili esterne.
    • exportall specifica che le funzioni di chiamata nella libreria condivisa sono richiamabili da programmi esterni.
    comando Open XL C/C++
    Ad esempio:
    ibm-clang -m64 -fvisibility=default -o libSample.so -I$JAVA_HOME/include -I$JAVA_HOME/include/zos Sample.c $JAVA_HOME/lib/j9vm/libjvm.x

    dove $JAVA_HOME è il percorso JAVA_HOME dell'installazione di IBM SDK.

    Gli elementi specifici di 'Open XL C/C++ nei comandi di compilazione e collegamento sono i seguenti:
    Tabella 2. elementi specifici del comando Open XL C/C++
    Opzione Descrizione
    ibm-clang Il comando che esegue il compilatore C di Open XL.
    -m64 Indica al compilatore di compilare la libreria condivisa di destinazione per piattaforme AMODE64 . solo a 64 bit.
    -fvisibility=default Questa opzione esporta tutte le funzioni e le variabili definite esternamente nell'unità di compilazione, in modo che un'applicazione DLL possa utilizzarle.
    Gli altri elementi condivisi nei comandi di compilazione e collegamento sono i seguenti:
    Tabella 3. Elementi comuni a XL e Open XL
    Opzione Descrizione
    -o libSample.so Il file di output, che è la libreria condivisa che si desidera creare. Il nome (il testo tra 'lib e '.so) deve corrispondere al nome fornito alle API Java 'System.load(filename) o 'System.loadLibrary(filename).
    --I Indica al compilatore di cercare nella directory $JAVA_HOME /include, oltre alle directory predefinite, i file di intestazione (in questo caso, i file di intestazione JNI). Cambiare $JAVA_HOME con il percorso JAVA_HOME dell'installazione di IBM SDK.
    --I Indica al compilatore di cercare nella directory $JAVA_HOME /include/zos, oltre alle directory predefinite, i file di intestazione (in questo caso, i file di intestazione JNI).
    Sample.c Il tuo programma C.
    $JAVA_HOME/lib/j9vm/libjvm.x Il file sidedeck che consente al codice nativo di collegare e risolvere le API JNI e Invocation.
  6. Eseguire l'applicazione Sample .
    Poiché si è utilizzata l'API Java 'System.loadLibrary per specificare la libreria condivisa di destinazione, è necessario assicurarsi che la variabile d'ambiente 'LIBPATH o la proprietà 'java.library.path includa la directory in cui risiede la libreria 'libSample.so.
    Ad esempio:
    LIBPATH=. java Sample
    oppure
    java -Djava.library.path=. Sample
    Il programma emette il messaggio seguente:
    Printing from native

Risultati

Ora è possibile utilizzare lo stesso framework per accedere alle librerie condivise native dalle applicazioni Java.