Ejemplo de utilización de bibliotecas compartidas en z/OS
Este ejemplo describe el proceso de uso de bibliotecas compartidas nativas con una aplicación Java™ en sistemas z/OS.
Acerca de esta tarea
Esta tarea demuestra cómo crear una aplicación Java que carga e invoca funciones C dentro de una biblioteca nativa compartida.
Procedimiento
- Crear una aplicación de ejemplo ' 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(); } }
Esta aplicación Java declara un método nativo estático '
Durante el bloque de inicialización de la clase estática que se ejecuta cuando la clase 'Sample.printFromNative()
, y llama a este método nativo desde el método 'main
.Sample
' se carga por primera vez, la llamada a 'System.loadLibrary("Sample")
' carga la biblioteca nativa de destino 'libSample.so
.Nota: La API 'System.loadLibrary(libname)
' añade el prefijo 'lib
y el sufijo '.so
' al nombre de la biblioteca que proporcione. El SDK busca la biblioteca compartida de destino dentro de la ruta de biblioteca especificada en la variable de entorno 'LIBPATH
. Si su biblioteca compartida nativa de destino es un conjunto de datos MVS, o si tiene una ruta absoluta o un nombre de biblioteca específicos, utilice en su lugar la API 'System.load(filename)
'. - La parte Java de la aplicación se ha completado, por lo que ahora puede compilarla:
javac Sample.java
- Utilice el mandato javac -h para crear un archivo de cabecera para el código nativo:
Este comando genera un archivo de cabecera C que se llama 'javac -h . Sample.java
Sample.h
, con las firmas de método JNI apropiadas para la implementación de su aplicación nativa. - Cree un archivo denominado
Sample.c
:
Este archivo proporciona la implementación nativa C del método Java#include <stdio.h> #include "Sample.h" JNIEXPORT void JNICALL Java_Sample_printFromNative(JNIEnv * env, jclass cls) { printf( "Printing from native\n" ); }
Sample.printFromNative()
. - Compila '
Sample.c
, lo enlaza, y lo enlaza en una librería compartida 'libSample.so
, que puede ser cargada y llamada dinámicamente desde una aplicación Java. Puede utilizar el compilador XL C/C++ u Open XL C/C++.
comando XL C/C++Para aplicaciones de 31 bits:
dondexlc -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
$JAVA_HOME
es la vía de acceso JAVA_HOME de la instalación del SDK de IBM.Para aplicaciones de 64 bits:
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
donde
$JAVA_HOME
es la vía de acceso JAVA_HOME de la instalación del SDK de IBM. El fichero de cabecera ' jni.h existe en ' $JAVA_HOME/include y ' libjvm.x ' está en ' $JAVA_HOME/lib/s390x/j9vm.Los elementos específicos de 'XL C/C++
' en los comandos de compilación y enlace son los siguientes:Tabla 1. Elementos específicos del comando XL C/C++ Opción Descripción xlc El comando que ejecuta el compilador XL C. -q64 Opción válida sólo para 64 bits. Indica al compilador que compile la biblioteca compartida de destino para las plataformas AMODE64. --W "l, xplink,
dll"La opción -W
se pasa a la fase de enlace del compilador. El enlazador crea una biblioteca compartida ' .so archivo, and uses the high-performance linkage XPLINK
.--W "c,langlvl(ampliado), float(ieee),xplink,
dll,exportall"La opción -W
se pasa a la fase de compilación del compilador.langlvl(extended)
habilita las extensiones de lenguaje que utilizan los archivos de cabecera JNI, como por ejemplolong long
.float(ieee)
indica al compilador que genere números e instrucciones binarios de coma flotante IEEE754 , que coincidan con los tipos primitivosfloat
ydouble
del lenguaje Java.xplink
indica al compilador que utilice la vinculación de alto rendimiento XPLINK, que coincide con la vinculación utilizada por la máquina virtual Java. En las plataformas de 31 bits, el Entorno Lingüístico admite la transición a otros vínculos (como el Vínculo del Sistema), a costa de otra longitud de ruta.dll
indica al compilador que genere el código DLL. El código DLL puede exportar o importar funciones y variables externas.exportall
especifica que los programas externos pueden invocar las funciones de llamada de la biblioteca compartida.
ComandoOpen XL C/C++Por ejemplo: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
donde $JAVA_HOME es la ruta JAVA_HOME de su instalación de IBM SDK.
Los elementos específicos de 'Open XL C/C++
' en los comandos de compilación y enlace son los siguientes:Tabla 2. elementos específicos del comando Open XL C/C++ Opción Descripción ibm-clang El comando que ejecuta el compilador Open XL C. -m64 Indica al compilador que compile la biblioteca compartida de destino para las plataformas AMODE64. sólo 64 bits. -fvisibility=por defecto Esta opción exporta todas las funciones y variables definidas externamente en la unidad de compilación para que una aplicación DLL pueda utilizarlas. El resto de elementos compartidos en los comandos de compilación y enlace son los siguientes:Tabla 3. Elementos comunes para XL y Open XL Opción Descripción -o libSample.so El archivo de salida, que es la biblioteca compartida que desea compilar. El nombre (el texto entre ' lib
y '.so
) debe coincidir con el nombre que proporcionó a las API Java 'System.load(filename)
o 'System.loadLibrary(filename)
.--I Indica al compilador que busque en el directorio $JAVA_HOME /include, además de en los directorios por defecto, archivos de cabecera (en este caso, archivos de cabecera JNI). Cambie $JAVA_HOME por la ruta JAVA_HOME de su instalación de IBM SDK. --I Indica al compilador que busque en el directorio $JAVA_HOME /include/zos, además de en los directorios por defecto, archivos de cabecera (en este caso, archivos de cabecera JNI). Sample.c El programa C. $JAVA_HOME/lib/j9vm/libjvm.x El archivo sidedeck que permite al código nativo enlazar y resolver las APIs JNI e Invocation. - Ejecute la aplicación
Sample
.Dado que ha utilizado la API Java "System.loadLibrary
" para especificar la biblioteca compartida de destino, debe asegurarse de que la variable de entorno "LIBPATH
" o la propiedad "java.library.path
" incluyen el directorio donde reside la biblioteca "libSample.so
".Por ejemplo:
orLIBPATH=. java Sample
java -Djava.library.path=. Sample
El programa genera el siguiente mensaje:Printing from native
Resultados
Ahora, puede utilizar el mismo marco para acceder a bibliotecas compartidas nativas desde aplicaciones Java.