Enlace de tiempo de ejecución JNI

JNI (Java™ Native Interface) habilita el enlace en tiempo de ejecución a bibliotecas nativas dinámicas y estáticas.

Consulte las secciones siguientes para obtener información específica de la plataforma:

Información específica de los sistemas AIX

Para el enlace de tiempo de ejecución, las aplicaciones se pueden enlazar mediante la opción del cargador -brtl. Si el enlace de tiempo de ejecución provoca un conflicto de símbolos, la aplicación deberá resolverlo renombrando el símbolo en el lado de la aplicación o desactivando el enlace de tiempo de ejecución.

Enlace dinámico en AIX

Para enlazar dinámicamente una biblioteca nativa, debe compilar los métodos nativos (funciones C o C++ llamadas por Java) en objetos compartidos AIX (bibliotecas cargadas dinámicamente). Por ejemplo, si sus métodos nativos se almacenan en el archivo nm.c, podría crear el objeto compartido con el siguiente mandato:
cc_r -qmkshrobj [-qarch=ppc | -q64] -Ijava_install_dir/include 
-o libnm.a nm.c
La opción -qmkshrobj inhabilita el enlace de tiempo de ejecución. Para obtener más información sobre los archivos de objetos compartidos, el enlace de tiempo de ejecución y el uso de las opciones de línea de mandatos de cc y ld, consulte:

Antes de ejecutar un programa Java que utilice métodos nativos, asegúrese de que LIBPATH contiene la lista de directorios que contienen los objetos compartidos para los métodos nativos. Para obtener más información sobre la creación de objetos compartidos de AIX , consulte Desarrollo de aplicaciones C y C++ en AIX . Vaya a https://www.ibm.com/redbooks y busque "SG245674".

Si establece el atributo setuid o setgid en los programas de código nativo JNI, ese valor cambia la variable de entorno LIBPATH efectiva. Este cambio podría producir un comportamiento inesperado o incorrecto con estos programas. Para obtener más información sobre este uso, consulte Developing and Porting C and C++ Applications on AIX en http://www.redbooks.ibm.com/abstracts/sg245674.html, sección 2.3.3.

Cuando crea un programa C o C++ que utiliza la API de invocación JNI para crear una máquina virtual Java y llama al código Java, utilice la opción -L para realizar las tareas siguientes:

  • Añada /usr/lib y /lib a la lista de directorios en los que se buscan objetos compartidos. Todos los programas necesitan objetos compartidos que estén almacenados en estos directorios.
  • Añada los directorios Java java_install_dir/jre/lib y java_install_dir/jre/lib/j9vm a la lista de directorios en los que se buscan objetos compartidos. Estos directorios contienen las bibliotecas compartidas de Java. También podrá efectuar un enlace con libjvm.so (mediante la opción -ljvm).

Por ejemplo, este código crea un programa C (invAPITest.c) que utiliza la API de invocación de JNI:

cc_r [-qarch=pwr4 | -q64] -Ijava_install_dir/include 
	-o invAPITest 
	-L/usr/lib 
	-L/lib 
	-Ljava_install_dir/jre/lib/j9vm 
	-Ljava_install_dir/jre/lib 
	-ljvm invAPITest.c

Cuando ejecute un programa C o C++ que utilice la API de invocación JNI para ejecutar clases Java, asegúrese de que la vía de acceso de clases se haya configurado correctamente para permitir que la JVM encuentre los archivos de clase. Si modifica la vía de acceso de clases de arranque Java, incluya los archivos SDK necesarios para ejecutar las aplicaciones.

Para determinar si un programa C o C++ que utiliza la API de invocación JNI se ha creado con la opción -bM:UR, utilice el mandato siguiente:

dump [-X64] -ov <program name> 

Se generará una salida similar a la siguiente:

>dump -X64 -ov <program name>
                        ***Object Module Header***
# Sections      Symbol Ptr      # Symbols       Opt Hdr Len     Flags
         4      0x0001a728           1305               120     0x1002
Flags=( EXEC DYNLOAD DEP_SYSTEM )
Timestamp = "14 Oct 03:26:43 2005"
Magic = 0x1f7  (64-bit XCOFF)

                        ***Optional Header***
Tsize        Dsize       Bsize       Tstart      Dstart
0x000127f8  0x00001b80  0x00000470  0x1000001f8  0x1100009f0

SNloader     SNentry     SNtext      SNtoc       SNdata
0x0004      0x0002      0x0001      0x0002      0x0002    

TXTalign     DATAalign   TOC         vstamp      entry
0x0005      0x0003      0x110002158  0x0001      0x110002040

maxSTACK     maxDATA     SNbss       magic       modtype
0x00000000  0x00000000  0x0003      0x010b        UR
Simodtypeno esUR, puede utilizar la variable de entorno LDR_CNTRL para hacer que los programas se comporten como si se compilaran con la opción de enlazador -bM:UR . Por ejemplo:
export LDR_CNTRL=USERREGS

Si necesita especificar varias opciones con LDR_CNTRL, separe las opciones con el símbolo @.

Las hebras Java creadas por la JVM utilizan el modelo pthreads POSIX que está soportado en AIX. Actualmente se trata de una correlación 1 a 1 con las hebras de kernel. Al desarrollar un programa JNI deberá ejecutarlo con un modelo de hebra 1 a 1 y un ámbito de contención de sistema si crea pthreads en su propio programa. Puede controlar este comportamiento utilizando el siguiente valor de entorno:
export AIXTHREAD_SCOPE=S

Otra opción es preestablecer el atributo de ámbito de la hebra en PTHREAD_SCOPE_SYSTEM utilizando la función AIX pthread_attr_setscope cuando se crea la hebra.

Puede almacenar métodos nativos tal como se indica a continuación:
Objeto compartido
Un objeto compartido es un archivo de objeto individual que tiene el bit SRE (Shared REusable) establecido en la cabecera XCOFF. El bit SRE indica al enlazador que este archivo está enlazado dinámicamente. Estos archivos suelen tener un nombre con el formato <filename> .o, pero también pueden denominarse lib<name> .a para permitir que el enlazador los busque con la opción -lname; pero estos archivos no son archivos de biblioteca de archivado.
Biblioteca compartida
Una biblioteca compartida es una biblioteca de archivado con el formato "ar" donde uno o varios de los miembros de archivado es un objeto compartido. Tenga en cuenta que esta biblioteca también puede contener archivos de objetos no compartidos que están enlazados estáticamente. El nombre de una biblioteca compartida tiene el formato lib<name> .a. Este formulario permite al enlazador buscar bibliotecas con la opción -lname.

Para obtener más información, consulte la documentación deAIX.

Los programas también pueden enlazarse dinámicamente con bibliotecas compartidas y objetos compartidos, por ejemplo con la familia de subrutinas dlopen(). La JVM enlaza de esta manera cuando carga bibliotecas nativas (por ejemplo, System.load(), System.loadLibrary(), Runtime.getRuntime().load(), Runtime.getRuntime().loadLibrary()).

Para obtener información sobre dlopen , consulte subrutina dlopen.

Para obtener información sobre los mecanismos de carga y enlace de AIX , consulte AIX Mecanismos de enlace y carga.

Para cargar una biblioteca compartida de AIX , realice una llamada a:
System.loadLibrary("<library>(<member>)")
donde <library> es el nombre del archivado de biblioteca compartida y <member> es el nombre de un miembro de archivado. Por ejemplo:
System.loadLibrary("libShared.a(libSample.o)")
Nota: Para asegurarse de que el enlace dinámico de bibliotecas nativas funciona correctamente, opcionalmente, puede implementar las funciones de ciclo de vida JNI_Onload() y JNI_OnUnload() en la biblioteca. Si ha implementado JNI_Onload(), la biblioteca nativa deberá exportarlo; de lo contrario, no será visible en tiempo de ejecución y la JVM dará por supuesto que la biblioteca solo necesita la versión JNI_VERSION_1.1 de JNI. Si se ha implementado JNI_OnUnload() también se deberá exportar. Si se ha implementado y exportado JNI_Onload(), se devolverá la última versión de JNI, como por ejemplo JNI_VERSION_1.8.

Enlace estático en AIX

Puede efectuar enlaces a bibliotecas JNI de forma estática, además de poder hacerlo de forma dinámica. Las bibliotecas estáticas pueden combinarse en la imagen de un lanzador personalizado que inicia un proceso de JVM con las API de invocación.

Supongamos que tenemos dos bibliotecas estáticas: testlibA y testlibB. Si intenta cargar la biblioteca testlibA en el programa Java mediante un comando como System.loadLibrary("testlibA"), la JVM primero busca en la imagen del programa ejecutable de lanzamiento una rutina llamada JNI_OnLoad_testlibA( ). Si encuentra esta rutina, la JVM utiliza esta biblioteca vinculada estáticamente para proporcionar definiciones JNI. Si no se encuentra la rutina, la JVM pasa a cargar la biblioteca testlibA de forma dinámica (por ejemplo, libtestlibA.so) buscando en las vías de acceso especificadas por -Djava.library.path (o LIBPATH).

En AIX, además de habilitar el enlace de tiempo de ejecución especificando -brtl, debe compilar con la opción -bexpall especificada. Este proceso garantiza que el lanzador exporte símbolos (como por ejemplo JNI_OnLoad_testlibA()) y también permite que las bibliotecas compartidas cargadas por el programa ejecutable (como por ejemplo el de la JVM) puedan buscar los símbolos. Para que la JVM efectúe un enlace de forma estática debe poder buscar en el programa ejecutable antes de intentar efectuar un enlace dinámico.

También puede crear un programa ejecutable con bibliotecas estáticas utilizando el siguiente mandato:
$ cc_r -qpic -brtl -bexpall -brtl testlibA.o testlibB.o -o <launcher>
donde < launcher> es el nombre de un programa ejecutable que contiene las imágenes de las bibliotecas testlibA y testlibB , además de ser un lanzador Java que inicia una JVM a través de las API de invocación.

La rutina de inicialización de la biblioteca JNI_OnLoad_L, para una biblioteca L, debe devolverJNI_VERSION_1_8(0x00010008).

Información específica de los sistemas Linux

Si el enlace de tiempo de ejecución provoca un conflicto de símbolos, la aplicación deberá resolverlo renombrando el símbolo en el lado de la aplicación o desactivando el enlace de tiempo de ejecución.

Enlace dinámico en Linux

Cuando crea un programa C o C++ que utiliza la API de invocación JNI para crear una máquina virtual Java y llama al código Java, utilice la opción -L para realizar las tareas siguientes:

  • Añada /usr/lib y /lib a la lista de directorios en los que se buscan objetos compartidos. Todos los programas necesitan objetos compartidos que estén almacenados en estos directorios.
  • Añada los directorios Java java_install_dir/jre/lib y java_install_dir/jre/lib/j9vm a la lista de directorios en los que se buscan objetos compartidos. Estos directorios contienen las bibliotecas compartidas de Java. También podrá efectuar un enlace con libjvm.so (mediante la opción -ljvm).

Por ejemplo, este código crea un programa C (invAPITest.c) que utiliza la API de invocación de JNI:

cc [-m32|-m64] -Ijava_install_dir/include 
	-o invAPITest 
	-L/usr/lib 
	-L/lib 
	-Ljava_install_dir/jre/lib/j9vm 
	-Ljava_install_dir/jre/lib 
	-ljvm invAPITest.c

Cuando ejecute un programa C o C++ que utilice la API de invocación JNI para ejecutar clases Java, asegúrese de que la vía de acceso de clases se haya configurado correctamente para permitir que la JVM encuentre los archivos de clase. Si modifica la vía de acceso de clases de arranque Java, incluya los archivos SDK necesarios para ejecutar las aplicaciones.

Para asegurarse de que una biblioteca JNI exporta las funciones que una aplicación Java debe resolver en tiempo de ejecución, puede examinar la biblioteca utilizando la herramienta nm . Por ejemplo, una biblioteca JNI denominada libjnitest.so que contiene las rutinas JNI fooImpl y barImpl deberá exportar los siguientes símbolos:

$ nm libjnitest.so
000537d0 T Java_mypackage_SampleClass_fooImpl
0004f020 T Java_mypackage_SampleClass_barImpl

De forma similar, el mandato objdump -T lista los símbolos exportados en una biblioteca compartida:

000537d0  g    DF .text  00000040  Base        0x60 
Java_mypackage_SampleClass_fooImpl
0004f020  g    DF .text  00000254  Base        0x60 
Java_mypackage_SampleClass_barImpl
Puede almacenar métodos nativos tal como se indica a continuación:
Biblioteca compartida
Una biblioteca compartida (u objeto compartido) en Linux es una biblioteca de enlace dinámico que se puede enlazar durante la compilación (enlace) o durante la ejecución (enlace en tiempo de ejecución). Mientras el enlace de tiempo de enlace en una biblioteca compartida se efectúa mediante la herramienta de edición de enlazador ld, el enlace en tiempo de ejecución utiliza la familia de funciones dlopen(3).

Los programas también pueden enlazarse dinámicamente con bibliotecas compartidas y objetos compartidos, por ejemplo con la familia de subrutinas dlopen(). La JVM enlaza de esta manera cuando carga bibliotecas nativas (por ejemplo, System.load(), System.loadLibrary(), Runtime.getRuntime().load(), Runtime.getRuntime().loadLibrary()).

Para obtener información sobre dlopen(3), consulte la documentación de Linux man y busque dlopen.

Nota: Para asegurarse de que el enlace dinámico de bibliotecas nativas funciona correctamente, opcionalmente, puede implementar las funciones de ciclo de vida JNI_Onload() y JNI_OnUnload() en la biblioteca. Si ha implementado JNI_Onload(), la biblioteca nativa deberá exportarlo; de lo contrario, no será visible en tiempo de ejecución y la JVM dará por supuesto que la biblioteca solo necesita la versión JNI_VERSION_1.1 de JNI. Si se ha implementado JNI_OnUnload() también se deberá exportar. Si se ha implementado y exportado JNI_Onload(), se devolverá la última versión de JNI, como por ejemplo JNI_VERSION_1.8.

Enlace estático en Linux

Puede efectuar enlaces a bibliotecas JNI de forma estática, además de poder hacerlo de forma dinámica. Las bibliotecas estáticas pueden combinarse en la imagen de un lanzador personalizado que inicia un proceso de JVM con las API de invocación.

Supongamos que tenemos dos bibliotecas estáticas: testlibA y testlibB. Si intenta cargar la biblioteca testlibA en el programa Java mediante un comando como System.loadLibrary("testlibA"), la JVM primero busca en la imagen del programa ejecutable de lanzamiento una rutina llamada JNI_OnLoad_testlibA( ). Si encuentra esta rutina, la JVM utiliza esta biblioteca vinculada estáticamente para proporcionar definiciones JNI. Si no se encuentra la rutina, la JVM pasa a cargar la biblioteca testlibA de forma dinámica (por ejemplo, libtestlibA.so) buscando en las vías de acceso especificadas por -Djava.library.path (o LD_LIBRARY_PATH).

En Linux, debe compilar con la opción -rdynamic especificada para garantizar que el lanzador exporte símbolos (como JNI_OnLoad_testlibA( ) y también permita que las bibliotecas compartidas que carga el programa ejecutable (como la de la JVM) busquen los símbolos. Para que la JVM efectúe un enlace de forma estática debe poder buscar en el programa ejecutable antes de intentar efectuar un enlace dinámico. Sin -rdynamic, los símbolos no estáticos se seguirán exportando desde el programa ejecutable, pero no serán visibles para las bibliotecas compartidas cargadas por el programa. El siguiente ejemplo muestra el uso de -rdynamic:

$ cc -rdynamic testlibA.o testlibB.o -o <launcher>

La rutina de inicialización de la biblioteca JNI_OnLoad_L, para una biblioteca L, debe devolverJNI_VERSION_1_8(0x00010008).

Información específica de los sistemas Windows

Si el enlace de tiempo de ejecución provoca un conflicto de símbolos, la aplicación deberá resolverlo renombrando el símbolo en el lado de la aplicación o desactivando el enlace de tiempo de ejecución.

Enlace dinámico en Windows

Cuando crea un programa C o C++ que utiliza la API de invocación JNI para crear una máquina virtual Java y llama al código Java, utilice la opción de enlazador /link /LIBPATH para realizar la tarea siguiente:

  • Añada los directorios Java java_install_dir\jre\bin\ y java_install_dir\jre\bin\j9vm a la lista de directorios en los que se buscan objetos compartidos. Estos directorios contienen las bibliotecas compartidas de Java. También podrá efectuar un enlace con jvm.dll (mediante la opción -ljvm).

En Windows, no se necesitan opciones especiales para el compilador de línea de mandatos cl.exe. Generalmente, se utiliza un compilador de Microsoft, por ejemplo, VC + +. Para obtener más información sobre las opciones de compilador, consulte la documentación del compilador que se está utilizando. De forma predeterminada, VC++ selecciona las bibliotecas que se encuentran en la variable de entorno %LIB%. La variable siempre debe apuntar hacia el subdirectorio \lib del SDK de VC++ como una de las vías de acceso de búsqueda para enlazar bibliotecas.

A continuación se muestra un bloque de mandatos típico para crear la prueba de API de invocación:
cl.exe /I java_install_dir\jre\include
	/FeinvAPITest 
	invAPITest.c 
	/link /LIBPATH:java_install_dir\jre\bin\j9vm 
	/LIBPATH:java_install_dir\jre\bin

Cuando ejecute un programa C o C++ que utilice la API de invocación JNI para ejecutar clases Java, asegúrese de que la vía de acceso de clases se haya configurado correctamente para permitir que la JVM encuentre los archivos de clase. Si modifica la vía de acceso de clases de arranque Java, incluya los archivos SDK necesarios para ejecutar las aplicaciones.

Para asegurarse de que una biblioteca JNI exporta las funciones que una aplicación Java debe resolver en tiempo de ejecución, puede examinar la biblioteca utilizando la herramienta dumpbin.exe (normalmente una parte de la instalación del SDK de VC++). Por ejemplo, una biblioteca JNI denominada jnitest.dll y que contiene las rutinas JNI fooImpl y barImpl deberá exportar los siguientes símbolos:
C:\>dumpbin.exe /EXPORTS jnitest.dll
Dump of file jnitest.dll

File Type: DLL

      Section contains the following exports for JNITEST.dll

00000000 characteristics
5412A472 time date stamp Fri Sep 12 03:44:50 2014
    0.00 version
       1 ordinal base
       5 number of functions
       5 number of names

ordinal hint RVA      name
...
     1   27 0000CE10 Java_mypackage_SampleClass_fooImpl = Java_mypackage_SampleClass_fooImpl
     2   28 000085A0 Java_mypackage_SampleClass_barImpl = Java_mypackage_SampleClass_barImpl
...

Para obtener más información sobre dumpbin.exe y sus opciones, consulte la documentación de MSDN.

Puede almacenar métodos nativos tal como se indica a continuación:
Bibliotecas de enlace dinámico
En Windows, los métodos JNI se almacenan normalmente en bibliotecas dinámicas denominadas bibliotecas de enlace dinámico (DLL). Las DLL contienen funciones y datos a los que se puede hacer referencia desde otro módulo de carga, por ejemplo desde una biblioteca dinámica o un programa ejecutable. Los métodos nativos se almacenan en DLL y se enlazan en tiempo de compilación, a través del proceso de enlace, o en tiempo de ejecución, cargando dinámicamente los métodos utilizando las funciones LoadLibrary() y LoadLibraryEx() de la API de Windows. Para obtener más información sobre la familia de funciones LoadLibrary(), consulte la documentación MSDN.
Nota: Para asegurarse de que el enlace dinámico de bibliotecas nativas funciona correctamente, opcionalmente, puede implementar las funciones de ciclo de vida JNI_Onload() y JNI_OnUnload() en la biblioteca. Si ha implementado JNI_Onload(), la biblioteca nativa deberá exportarlo; de lo contrario, no será visible en tiempo de ejecución y la JVM dará por supuesto que la biblioteca solo necesita la versión JNI_VERSION_1.1 de JNI. Si se ha implementado JNI_OnUnload() también se deberá exportar. Si se ha implementado y exportado JNI_Onload(), se devolverá la última versión de JNI, como por ejemplo JNI_VERSION_1.8.

Enlaces estáticos en Windows

Puede efectuar enlaces a bibliotecas JNI de forma estática, además de poder hacerlo de forma dinámica. Las bibliotecas estáticas pueden combinarse en la imagen de un lanzador personalizado que inicia un proceso de JVM con las API de invocación.

Supongamos que tenemos dos bibliotecas estáticas: testlibA y testlibB. Si intenta cargar la biblioteca testlibA en el programa Java mediante un comando como System.loadLibrary("testlibA"), la JVM primero busca en la imagen del programa ejecutable de lanzamiento una rutina llamada JNI_OnLoad_testlibA( ). Si encuentra esta rutina, la JVM utiliza esta biblioteca vinculada estáticamente para proporcionar definiciones JNI. Si no se encuentra la rutina, la JVM pasa a cargar la biblioteca testlibA de forma dinámica (por ejemplo, testlibA.dll) buscando en las vías de acceso especificadas por -Djava.library.path (o PATH).

Windows no impone ninguna opción especial que se deba especificar al crear un programa ejecutable de lanzador.

La rutina de inicialización de la biblioteca JNI_OnLoad_L, para una biblioteca L, debe devolverJNI_VERSION_1_8(0x00010008).

Información específica de los sistemas z/OS

Si el enlace de tiempo de ejecución provoca un conflicto de símbolos, la aplicación deberá resolverlo renombrando el símbolo en el lado de la aplicación o desactivando el enlace de tiempo de ejecución.

Enlace dinámico en z/OS

Cuando crea un programa C o C++ que utiliza la API de invocación JNI para crear una máquina virtual Java y llama al código Java, utilice la opción -L para realizar las tareas siguientes:

  • Añada /usr/lib y /lib a la lista de directorios en los que se buscan objetos compartidos. Todos los programas necesitan objetos compartidos que estén almacenados en estos directorios.
  • Añada los directorios Java java_install_dir/jre/lib y java_install_dir/jre/lib/j9vm a la lista de directorios en los que se buscan objetos compartidos. Estos directorios contienen las bibliotecas compartidas de Java. También podrá efectuar un enlace con libjvm.so (mediante la opción -ljvm).

Por ejemplo, este código crea un iniciador de API de invocación denominadoinvAPITest mediante la compilación del programa C invAPITest.c:

cc [-q32|-q64] -Ijava_install_dir/jre/include 
	-o invAPITest 
	-L/usr/lib 
	-L/lib 
	-Ljava_install_dir/jre/lib/j9vm 
	-Ljava_install_dir/jre/lib 
	-ljvm invAPITest.c

El valor -q32 o -q64 especifica el modelo de datos en el que se crea el programa. Si omite estos valores se utilizará el modelo de datos predeterminado.

Cuando ejecute un programa C o C++ que utilice la API de invocación JNI para ejecutar clases Java, asegúrese de que la vía de acceso de clases se haya configurado correctamente para permitir que la JVM encuentre los archivos de clase. Si modifica la vía de acceso de clases de arranque Java, incluya los archivos SDK necesarios para ejecutar las aplicaciones.

Para asegurarse de que una biblioteca JNI exporta las funciones que una aplicación Java debe resolver en tiempo de ejecución, puede examinar la biblioteca utilizando la herramienta nm . Por ejemplo, una biblioteca JNI denominada libjnitest.so y que contiene las rutinas JNI fooImpl y barImpl deberá exportar los siguientes símbolos:

$nm libjnitest.so
     255552 T Java_mypackage_SampleClass_fooImpl
     255528 T Java_mypackage_SampleClass_barImpl

Para obtener más información, consulte Valores predeterminados de opción de compilador.

Puede almacenar métodos nativos tal como se indica a continuación:
Bibliotecas de enlace dinámico
En sistemas IBM Z® , los métodos JNI normalmente se almacenan en bibliotecas dinámicas denominadas bibliotecas de enlace dinámico (DLL). Las DLL contienen funciones y datos a los que se puede hacer referencia desde otro módulo de carga, por ejemplo desde una biblioteca dinámica o un programa ejecutable. Los métodos nativos se almacenan en DLL y se enlazan en tiempo de compilación, a través del proceso de enlace, o en tiempo de ejecución, cargando dinámicamente los métodos utilizando la IBM Z dllload o la API compatible con POSIX dlopen. Para obtener más información sobre las funciones dllload () y dlopen (), consulte Carga de una DLL.

Los programas también pueden enlazarse dinámicamente con bibliotecas compartidas y objetos compartidos, por ejemplo con las familias de subrutinas dlopen() o dllload(). La JVM enlaza de esta manera cuando carga bibliotecas nativas (por ejemplo, System.load(), System.loadLibrary(), Runtime.getRuntime().load(), Runtime.getRuntime().loadLibrary()).

Para obtener información sobre estas subrutinas, consulte dlopen () y dllload ().

Nota: Para asegurarse de que el enlace dinámico de bibliotecas nativas funciona correctamente, opcionalmente, puede implementar las funciones de ciclo de vida JNI_Onload() y JNI_OnUnload() en la biblioteca. Si ha implementado JNI_Onload(), la biblioteca nativa deberá exportarlo; de lo contrario, no será visible en tiempo de ejecución y la JVM dará por supuesto que la biblioteca solo necesita la versión JNI_VERSION_1.1 de JNI. Si se ha implementado JNI_OnUnload() también se deberá exportar. Si se ha implementado y exportado JNI_Onload(), se devolverá la última versión de JNI, como por ejemplo JNI_VERSION_1.8.

Enlace estático en z/OS

Puede efectuar enlaces a bibliotecas JNI de forma estática, además de poder hacerlo de forma dinámica. Las bibliotecas estáticas pueden combinarse en la imagen de un lanzador personalizado que inicia un proceso de JVM con las API de invocación.

Supongamos que tenemos dos bibliotecas estáticas: testlibA y testlibB. Si intenta cargar la biblioteca testlibA en el programa Java mediante un comando como System.loadLibrary("testlibA"), la JVM primero busca en la imagen del programa ejecutable de lanzamiento una rutina llamada JNI_OnLoad_testlibA( ). Si encuentra esta rutina, la JVM utiliza esta biblioteca vinculada estáticamente para proporcionar definiciones JNI. Si no se encuentra la rutina, la JVM pasa a cargar la biblioteca testlibA de forma dinámica (por ejemplo, libtestlibA.so) buscando en las vías de acceso especificadas por -Djava.library.path (o LIBPATH).

En sistemas IBM Z , debe especificar las opciones siguientes al crear:
  • Wc,DLL, para asegurarse de que el programa ejecutable se crea como una DLL
  • Wc,EXPORTALL, para asegurarse de que los símbolos del programa ejecutable se exportan y quedan disponibles para la búsqueda por parte de las bibliotecas compartidas cargadas por el programa.
Estas opciones permiten que el programa ejecutable lanzador pueda exportar símbolos (como por ejemplo JNI_Onload_testlibA()) para que la JVM pueda buscarlos antes de intentar efectuar un enlace dinámico.
En el siguiente ejemplo se utilizan líneas de compilación y de enlace para garantizar que las bibliotecas estáticas testlibA y testlibB estén enlazadas al lanzador, creado como DLL, y exporten todos los símbolos.
cc -c -Wc,DLL,EXPORTALL launcher.c -o launcher.o
cc testlibA.o testlibB.o launcher.o -o launcher

También puede eliminar EXPORTALL, en cuyo caso el programa exporta símbolos específicos mediante #pragma export. Para obtener más información, consulte #pragma export.

Nota: En sistemas IBM Z , un programa ejecutable debe compilarse como DLL (Dynamic Link Library) además de exportar símbolos, si un programa ejecutable empaqueta rutinas JNI a las que el programa Java debe hacer referencia, utilizando enlaces estáticos. Si un programa ejecutable IBM Z define y exporta JNI_OnLoad_testlibA, pero no se ha creado como DLL (es decir, no se ha especificado -Wc,DLL ), es probable que falle el enlace estático, porque el tiempo de ejecución no puede resolver de nuevo el símbolo del programa ejecutable.

La rutina de inicialización de la biblioteca JNI_OnLoad_L, para una biblioteca L, debe devolverJNI_VERSION_1_8(0x00010008).