Beispiel für die Verwendung gemeinsam genutzter Bibliotheken unter z/OS

Dieses Beispiel beschreibt den Prozess der Verwendung nativer gemeinsam genutzter Bibliotheken mit einer Java™-Anwendung auf z/OS.

Informationen zu dieser Task

Diese Aufgabe demonstriert, wie man eine Java-Anwendung erstellt, die C-Funktionen innerhalb einer nativen Shared Library lädt und aufruft.

Vorgehensweise

  1. Erstellen Sie eine Beispielanwendung ' 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();
        }
    }

    Diese Java-Anwendung deklariert eine statische systemeigene Methode " Sample.printFromNative() und ruft diese systemeigene Methode über die Methode " main auf.

    Während des Initialisierungsblocks der statischen Klasse, der beim ersten Laden der Klasse " Sample ausgeführt wird, lädt der Aufruf von " System.loadLibrary("Sample") die native Zielbibliothek " libSample.so.
    Hinweis: Die API " System.loadLibrary(libname) fügt dem von Ihnen angegebenen Bibliotheksnamen den Präfix " lib und das Suffix " .so " hinzu. Das SDK sucht innerhalb des in der Umgebungsvariablen ' LIBPATH angegebenen Bibliothekspfads nach der gemeinsamen Zielbibliothek. Wenn Ihre native Shared Library ein MVS-Datensatz ist oder Sie einen bestimmten absoluten Pfad oder Bibliotheksnamen haben, verwenden Sie stattdessen die API " System.load(filename).
  2. Der Java-Teil der Anwendung ist vollständig, Sie können ihn jetzt kompilieren:
    javac Sample.java
  3. Erstellen Sie mit dem Befehl javac -h eine Headerdatei für den nativen Code:
    javac -h . Sample.java
    Dieser Befehl generiert eine C-Header-Datei mit dem Namen " Sample.h mit den entsprechenden JNI-Methodensignaturen für Ihre native Anwendungsimplementierung.
  4. Erstellen Sie eine Datei mit dem Namen Sample.c:
    #include <stdio.h>
    #include "Sample.h"
    
    JNIEXPORT void JNICALL Java_Sample_printFromNative(JNIEnv * env, jclass cls) {
      printf( "Printing from native\n" );
    }
    Diese Datei stellt die native C-Implementierung der Java-Methode Sample.printFromNative() bereit.
  5. Kompilieren Sie ' Sample.c, verknüpfen Sie es und binden Sie es in eine gemeinsam genutzte Bibliothek ' libSample.so, die von einer Java-Anwendung geladen und dynamisch aufgerufen werden kann. Sie können entweder XL C/C++ oder Open XL C/C++ Compiler verwenden.

    XL C/C++
    Für 31-Bit-Anwendungen:
    xlc -W "l,xplink,dll" -W "c,langlvl(extended),float(ieee),xplink,dll,exportall" -o libSample.so -I/$JAVA_HOME/include Sample.c  /$JAVA_HOME/lib/s390x/j9vm/libjvm.x
    Dabei steht $JAVA_HOME für den JAVA_HOME-Pfad Ihrer IBM SDK-Installation.

    Für 64-Bit-Anwendungen:

    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/s390x/libjvm.x

    Dabei steht $JAVA_HOME für den JAVA_HOME-Pfad Ihrer IBM SDK-Installation. Die Header-Datei ' jni.h existiert unter ' $JAVA_HOME/include und ' libjvm.x befindet sich in ' $JAVA_HOME/lib/s390x/j9vm.

    Die ' XL C/C++ -spezifischen Elemente in den Kompilier- und Link-Befehlen sind wie folgt:
    Tabelle 1. XL C/C++ befehlsspezifische Elemente
    Option Beschreibung
    XLC Der Befehl, der den XL-C-Compiler ausführt.
    -q64 Diese Option gilt nur für 64-Bit. Weist den Compiler an, die gemeinsam genutzte Zielbibliothek für AMODE64 -Plattformen zu kompilieren
    --W "l,xplink,dll" Die Option -W wird an die Linkphase des Compilers übergeben. Der Linker erstellt eine gemeinsame Bibliothek ' .so Datei, and uses the high-performance linkage XPLINK.
    --W "c,langlvl(erweitert),
    float(ieee),
    xplink,
    dll,exportall"
    Die Option -W wird an die Kompilierungsphase des Compilers übergeben.
    • langlvl(extended) aktiviert Spracherweiterungen, die von den JNI-Headerdateien wie long longverwendet werden.
    • float(ieee) weist den Compiler an, binäre IEEE754 Gleitkommazahlen und -anweisungen zu generieren, die den primitiven float -und double -Typen der Java-Sprache entsprechen.
    • xplink weist den Compiler an, die leistungsstarke Verknüpfung XPLINK zu verwenden, die der Verknüpfung entspricht, die von der virtuellen Java-Maschine verwendet wird. Auf 31-Bit-Plattformen unterstützt die Sprachumgebung den Übergang zu anderen Verknüpfungen (z. B. Systemverknüpfung), allerdings auf Kosten einer anderen Pfadlänge.
    • dll weist den Compiler an, DLL-Code zu erzeugen. Der DLL-Code kann Funktionen und externe Variablen exportieren oder importieren.
    • exportall gibt an, dass Aufruffunktionen in der gemeinsam genutzten Bibliothek von externen Programmen aufgerufen werden können.
    Open XL C/C++
    Beispiel:
    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

    wobei $JAVA_HOME der JAVA_HOME-Pfad Ihrer IBM SDK-Installation ist.

    Die ' Open XL C/C++ -spezifischen Elemente in den Kompilier- und Link-Befehlen sind wie folgt:
    Tabelle 2. Open XL C/C++ befehlsspezifische Elemente
    Option Beschreibung
    ibm-clang Der Befehl, der den Open XL C-Compiler ausführt.
    -m64 Weist den Compiler an, die gemeinsam genutzte Zielbibliothek für AMODE64 -Plattformen zu kompilieren nur 64-Bit.
    -fvisibility=default Diese Option exportiert alle extern definierten Funktionen und Variablen in der Kompiliereinheit, so dass eine DLL-Anwendung sie verwenden kann.
    Die übrigen gemeinsamen Elemente in den Kompilier- und Link-Befehlen sind wie folgt:
    Tabelle 3. Gemeinsame Elemente für XL und Open XL
    Option Beschreibung
    -o libSample.so Die Ausgabedatei, die die gemeinsam genutzte Bibliothek ist, die Sie erstellen wollen. Der Name (der Text zwischen ' lib und ' .so) muss mit dem Namen übereinstimmen, den Sie den Java-APIs ' System.load(filename) oder ' System.loadLibrary(filename) gegeben haben.
    --I Weist den Compiler an, zusätzlich zu den Standardverzeichnissen im Verzeichnis $JAVA_HOME /include nach Header-Dateien (in diesem Fall JNI-Header-Dateien) zu suchen. Ändern Sie $JAVA_HOME in den JAVA_HOME-Pfad Ihrer IBM SDK-Installation.
    --I Weist den Compiler an, zusätzlich zu den Standardverzeichnissen im Verzeichnis $JAVA_HOME /include/zos nach Header-Dateien (in diesem Fall JNI-Header-Dateien) zu suchen.
    Sample.c Das C-Programm.
    $JAVA_HOME/lib/j9vm/libjvm.x Die Sidedeck-Datei, die es nativem Code ermöglicht, die JNI- und Invocation-APIs zu verknüpfen und aufzulösen.
  6. Führen Sie die Sample -Anwendung aus.
    Da Sie die Java-API ' System.loadLibrary verwendet haben, um die gemeinsame Zielbibliothek anzugeben, müssen Sie sicherstellen, dass entweder die Umgebungsvariable ' LIBPATH oder die Eigenschaft ' java.library.path das Verzeichnis enthält, in dem sich die Bibliothek ' libSample.so befindet.
    Beispiel:
    LIBPATH=. java Sample
    oder
    java -Djava.library.path=. Sample
    Das Programm gibt die folgende Nachricht aus:
    Printing from native

Ergebnisse

Jetzt können Sie dasselbe Framework verwenden, um von Java-Anwendungen aus auf native Shared Libraries zuzugreifen.