Liaison d'exécution JNI

L'interface JNI (Java™ Native Interface) permet la liaison d'exécution à des bibliothèques natives dynamiques et statiques.

Consultez les sections suivantes pour des informations spécifiques à chaque plateforme :

Informations spécifiques aux systèmes AIX

Pour les liens d'exécution, les applications peuvent être liées à l'aide de l'option du programme de chargement -brtl. Si la liaison à l'exécution génère un conflit de symboles, vous devez soit le résoudre en renommant le symbole côté application, soit désactiver la liaison à l'exécution.

Liaison dynamique dans AIX

Pour lier dynamiquement une bibliothèque native, vous devez compiler vos méthodes natives (fonctions C ou C++ appelées par Java) en objets partagés AIX (bibliothèques chargées dynamiquement). Par exemple, si vos méthodes natives étaient stockées dans le fichier nm.c, vous pourriez créer l'objet partagé avec la commande suivante :
cc_r -qmkshrobj [-qarch=ppc | -q64] -Ijava_install_dir/include 
-o libnm.a nm.c
L'option -qmkshrobj désactive la liaison d'exécution. Pour plus d'informations sur les fichiers d'objets partagés, la liaison d'exécution et l'utilisation des options de ligne de commande cc et ld, voir :

Avant d'exécuter un programme Java qui utilise des méthodes natives, vérifiez que LIBPATH contient la liste des répertoires qui contiennent les objets partagés pour les méthodes natives. Pour plus d'informations sur la génération d'objets partagés AIX , voir C and C++ Application Development on AIX . Accédez à https://www.ibm.com/redbooks et recherchez "SG245674".

Si vous définissez l'attribut setuid ou setgid sur les programmes de code natif JNI, ce paramètre change la variable d'environnement LIBPATH effective. Cette modification peut provoquer un comportement inattendu ou incorrect de ces programmes. Pour plus d'informations sur cette utilisation, voir Developing and Porting C and C++ Applications on AIX à l'adresse http://www.redbooks.ibm.com/abstracts/sg245674.html, section 2.3.3.

Lorsque vous générez un programme C ou C++ qui utilise l'API JNI Invocation pour créer une machine virtuelle Java et appelle du code Java, utilisez l'option -L pour effectuer les tâches suivantes:

  • Ajoutez /usr/lib et /lib à la liste des répertoires qui sont recherchés pour les objets partagés. Tous les programmes nécessitent les objets partagés stockés dans ces répertoires.
  • Ajoutez vos répertoires Java java_install_dir/jre/lib et java_install_dir/jre/lib/j9vm à la liste des répertoires dans lesquels sont recherchés les objets partagés. Ces répertoires contiennent les bibliothèques partagées Java. Vous devez également lier votre programme à libjvm.so (en utilisant l'option -ljvm).

Par exemple, ce code génère un programme C (invAPITest.c) qui utilise l'API d'appel 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

Lorsque vous exécutez un programme C ou C++ qui utilise l'API JNI Invocation pour exécuter des classes Java, vérifiez que le chemin d'accès aux classes est configuré correctement pour permettre à la machine virtuelle Java de trouver vos fichiers de classe. Si vous modifiez le chemin d'accès aux classes d'amorçage Java, incluez les fichiers SDK nécessaires à l'exécution de vos applications.

Pour déterminer si un programme C ou C++ utilisant l'API d'appel JNI a été créé avec l'option -bM:UR, utilisez la commande suivante :

dump [-X64] -ov <program name> 

Une sortie similaire à la suivante sera générée :

>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
Si l'élément XMLmodtypen'est pasUR, vous pouvez utiliser la variable d'environnement LDR_CNTRL pour que les programmes se comportent comme s'ils étaient compilés avec l'option de liage -bM:UR . Par exemple :
export LDR_CNTRL=USERREGS

Si vous devez spécifier plusieurs options avec LDR_CNTRL, séparez ces options avec le symbole @.

Les unités d'exécution Java créées par la machine virtuelle Java utilisent le modèle POSIX pthreads pris en charge sous AIX. Actuellement, cette approche est un mappage 1 à 1 avec les unités d'exécution de noyau. Lorsque vous développez un programme JNI, vous devez utiliser un modèle d'unité d'exécution 1 à 1 et une portée de conflit système si vous créez des unités d'exécution pthreads dans votre propre programme. Vous pouvez contrôler cela à l'aide du paramètre d'environnement suivant :
export AIXTHREAD_SCOPE=S

Une autre option consiste à prédéfinir l'attribut de portée de l'unité d'exécution sur PTHREAD_SCOPE_SYSTEM à l'aide de la fonction AIX pthread_attr_setscope lors de la création de l'unité d'exécution.

Vous pouvez stocker les méthodes natives comme suit :
Objet partagé
Un objet partagé est un fichier objet unique dont le bit SRE (Shared REusable) est défini dans l'en-tête XCOFF. Le bit SRE indique à l'éditeur de liens que ce fichier est lié dynamiquement. Ces fichiers ont généralement le format de nom <filename>.o, mais ils peuvent également être nommés lib<name> .a pour permettre à l'éditeur de liens de rechercher ces fichiers avec l'option -lname , mais il ne s'agit pas de fichiers de bibliothèque d'archivage.
Bibliothèque partagée
Une bibliothèque partagée est un bibliothèque archive de format "ar" dans laquelle un ou plusieurs des membres d'archive est un objet partagé. Cette bibliothèque peut aussi contenir des fichiers objet non partagés qui sont liés statiquement. Une bibliothèque partagée porte un nom de la forme lib<name> .a. Ce formulaire permet à l'éditeur de liens de rechercher des bibliothèques avec l'option -lname.

Pour plus d'informations, voir la documentationAIX.

Les programmes peuvent également se lier dynamiquement à des bibliothèques partagées et des objets partagés, par exemple, en utilisant la famille de sous-routines dlopen(). La JVM se lie de cette façon lorsqu'elle charge des bibliothèques natives (par exemple System.load(), System.loadLibrary(), Runtime.getRuntime().load(), Runtime.getRuntime().loadLibrary()).

Pour plus d'informations sur dlopen , voir dlopen Subroutine.

Pour plus d'informations sur les mécanismes de chargement et de liaison AIX , voir AIX Mécanismes de liaison et de chargement.

Pour charger une bibliothèque partagée AIX , effectuez un appel à:
System.loadLibrary("<library>(<member>)")
<library> est le nom de l'archive de bibliothèque partagée et <member> est le nom d'un membre d'archivage. Par exemple :
System.loadLibrary("libShared.a(libSample.o)")
Remarque: Pour vous assurer que la liaison dynamique des bibliothèques natives fonctionne correctement, vous pouvez, en option, implémenter les fonctions de cycle de vie JNI_Onload() et JNI_OnUnload() dans la bibliothèque. Si vous avez implémenté JNI_Onload(), la bibliothèque native doit l'exporter. Autrement, elle n'est pas visible par l'exécution et la JVM suppose alors que la bibliothèque a seulement besoin de la version JNI JNI_VERSION_1.1. Si la fonction JNI_OnUnload() a été implémentée, elle doit être exportée. Si JNI_Onload() est implémentée et exportée, la dernière version de JNI est retournée ; par exemple, JNI_VERSION_1.8.

Liaison statique dans AIX

Vous pouvez lier statiquement le programme à des bibliothèques JNI, en plus de le lier dynamiquement. Les bibliothèques statiques peuvent être combinées dans l'image d'un lanceur personnalisé qui lance un processus de JVM en utilisant les API Invocation.

Supposez les deux bibliothèques statiques testlibA et testlibB. Si vous tentez de charger la bibliothèque testlibA dans le programme Java en utilisant une commande telle que System.loadLibrary("testlibA"), la JVM recherche d'abord dans l'image du programme exécutable de lancement une routine nommée JNI_OnLoad_testlibA( ). Si cette routine est trouvée, la JVM utilise cette bibliothèque liée statiquement pour fournir des définitions JNI. Si la routine n'est pas trouvée, la JVM charge dynamiquement la bibliothèque testlibA (par exemple, libtestlibA.so) en examinant les chemins spécifiés par -Djava.library.path (ou LIBPATH).

Sous AIX, en plus d'activer la liaison d'exécution en spécifiant -brtl, vous devez générer avec l'option -bexpall spécifiée. Ce processus garantit que le lanceur exporte les symboles (tels que JNI_OnLoad_testlibA()) et permet également que les bibliothèques partagées chargées par le programme exécutable (tel que celui de la JVM) puissent rechercher les symboles. Pour que la JVM se lie statiquement, elle doit pouvoir regarder dans le programme exécutable avant toute tentative de liaison dynamique.

Vous pouvez également générer un programme exécutable avec des bibliothèques statiques en utilisant la commande suivante :
$ cc_r -qpic -brtl -bexpall -brtl testlibA.o testlibB.o -o <launcher>
< launcher> est le nom d'un programme exécutable qui contient les images des bibliothèques testlibA et testlibB , ainsi que le nom d'un lanceur Java qui lance une machine virtuelle Java via les API d'appel.

La routine d'initialisation de la bibliothèque JNI_OnLoad_L, pour une bibliothèque L, doit renvoyerJNI_VERSION_1_8(0x00010008).

Informations spécifiques aux systèmes Linux

Si la liaison à l'exécution génère un conflit de symboles, vous devez soit le résoudre en renommant le symbole côté application, soit désactiver la liaison à l'exécution.

Liaison dynamique dans Linux

Lorsque vous générez un programme C ou C++ qui utilise l'API JNI Invocation pour créer une machine virtuelle Java et appelle du code Java, utilisez l'option -L pour effectuer les tâches suivantes:

  • Ajoutez /usr/lib et /lib à la liste des répertoires qui sont recherchés pour les objets partagés. Tous les programmes nécessitent les objets partagés stockés dans ces répertoires.
  • Ajoutez vos répertoires Java java_install_dir/jre/lib et java_install_dir/jre/lib/j9vm à la liste des répertoires dans lesquels sont recherchés les objets partagés. Ces répertoires contiennent les bibliothèques partagées Java. Vous devez également lier votre programme à libjvm.so (en utilisant l'option -ljvm).

Par exemple, ce code génère un programme C (invAPITest.c) qui utilise l'API d'appel 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

Lorsque vous exécutez un programme C ou C++ qui utilise l'API JNI Invocation pour exécuter des classes Java, vérifiez que le chemin d'accès aux classes est configuré correctement pour permettre à la machine virtuelle Java de trouver vos fichiers de classe. Si vous modifiez le chemin d'accès aux classes d'amorçage Java, incluez les fichiers SDK nécessaires à l'exécution de vos applications.

Pour vous assurer qu'une bibliothèque JNI exporte les fonctions qu'une application Java doit résoudre lors de l'exécution, vous pouvez examiner la bibliothèque à l'aide de l'outil nm . Par exemple, la bibliothèque JNI libjnitest.so qui contient les routines JNI fooImpl et barImpl doit exporter les symboles suivants :

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

De même, la commande objdump -T liste les symboles exportés dans une bibliothèque partagée :

000537d0  g    DF .text  00000040  Base        0x60 
Java_mypackage_SampleClass_fooImpl
0004f020  g    DF .text  00000254  Base        0x60 
Java_mypackage_SampleClass_barImpl
Vous pouvez stocker les méthodes natives comme suit :
Bibliothèque partagée
Une bibliothèque partagée (ou un objet partagé) sous Linux est une bibliothèque de liaison dynamique qui peut être liée au moment de la génération (liaison au moment de la liaison) ou au moment de l'exécution (liaison au moment de l'exécution). La liaison link-time linking par rapport à une bibliothèque partagée est effectuée en utilisant l'éditeur de liaison ld, mais la liaison runtime linking utilise la famille de fonctions dlopen(3).

Les programmes peuvent également se lier dynamiquement à des bibliothèques partagées et des objets partagés, par exemple, en utilisant la famille de sous-routines dlopen(). La JVM se lie de cette façon lorsqu'elle charge des bibliothèques natives (par exemple System.load(), System.loadLibrary(), Runtime.getRuntime().load(), Runtime.getRuntime().loadLibrary()).

Pour plus d'informations sur dlopen(3), consultez la documentation de l'utilisateur Linux et recherchez dlopen.

Remarque: Pour vous assurer que la liaison dynamique des bibliothèques natives fonctionne correctement, vous pouvez, en option, implémenter les fonctions de cycle de vie JNI_Onload() et JNI_OnUnload() dans la bibliothèque. Si vous avez implémenté JNI_Onload(), la bibliothèque native doit l'exporter. Autrement, elle n'est pas visible par l'exécution et la JVM suppose alors que la bibliothèque a seulement besoin de la version JNI JNI_VERSION_1.1. Si la fonction JNI_OnUnload() a été implémentée, elle doit être exportée. Si JNI_Onload() est implémentée et exportée, la dernière version de JNI est retournée ; par exemple, JNI_VERSION_1.8.

Liaison statique dans Linux

Vous pouvez lier statiquement le programme à des bibliothèques JNI, en plus de le lier dynamiquement. Les bibliothèques statiques peuvent être combinées dans l'image d'un lanceur personnalisé qui lance un processus de JVM en utilisant les API Invocation.

Supposez les deux bibliothèques statiques testlibA et testlibB. Si vous tentez de charger la bibliothèque testlibA dans le programme Java en utilisant une commande telle que System.loadLibrary("testlibA"), la JVM recherche d'abord dans l'image du programme exécutable de lancement une routine nommée JNI_OnLoad_testlibA( ). Si cette routine est trouvée, la JVM utilise cette bibliothèque liée statiquement pour fournir des définitions JNI. Si la routine n'est pas trouvée, la JVM charge dynamiquement la bibliothèque testlibA (par exemple, libtestlibA.so) en examinant les chemins spécifiés par -Djava.library.path (ou LD_LIBRARY_PATH).

Sur Linux, vous devez construire avec l'option -rdynamic spécifiée pour vous assurer que le lanceur exporte les symboles (tels que JNI_OnLoad_testlibA( ) et permet également aux bibliothèques partagées qui sont chargées par le programme exécutable (comme celle de la JVM) de rechercher les symboles. Pour que la JVM se lie statiquement, elle doit pouvoir regarder dans le programme exécutable avant toute tentative de liaison dynamique. Sans -rdynamic, les symboles non statiques sont toujours exportés depuis le programme exécutable, mais ils ne sont pas visibles par les bibliothèques partagées chargées par le programme. L'exemple suivant montre l'utilisation de -rdynamic:

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

La routine d'initialisation de la bibliothèque JNI_OnLoad_L, pour une bibliothèque L, doit renvoyerJNI_VERSION_1_8(0x00010008).

Informations spécifiques aux systèmes Windows

Si la liaison à l'exécution génère un conflit de symboles, vous devez soit le résoudre en renommant le symbole côté application, soit désactiver la liaison à l'exécution.

Liaison dynamique dans Windows

Lorsque vous générez un programme C ou C++ qui utilise l'API JNI Invocation pour créer une machine virtuelle Java et appelle du code Java, utilisez l'option d'éditeur de liens /link /LIBPATH pour effectuer la tâche suivante:

  • Ajoutez vos répertoires Java java_install_dir\jre\bin\ et java_install_dir\jre\bin\j9vm à la liste des répertoires dans lesquels sont recherchés les objets partagés. Ces répertoires contiennent les bibliothèques partagées Java. Vous devez également lier votre programme à jvm.dll (en utilisant l'option -ljvm).

Sous Windows, aucune option spéciale n'est requise pour le compilateur de ligne de commande cl.exe. En règle générale, un compilateur Microsoft est utilisé, par exemple VC + +. Pour plus d'informations sur les options de compilation, voir la documentation du compilateur utilisé. Par défaut, VC++ sélectionne les bibliothèques présentes dans la variable d'environnement %LIB%. Cette variable doit toujours désigner le sous-répertoire \lib du SDK VC++ parmi les chemins de recherche des bibliothèques de liaison.

Voici un bloc de commandes type pour créer un test d'API Invocation :
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

Lorsque vous exécutez un programme C ou C++ qui utilise l'API JNI Invocation pour exécuter des classes Java, vérifiez que le chemin d'accès aux classes est configuré correctement pour permettre à la machine virtuelle Java de trouver vos fichiers de classe. Si vous modifiez le chemin d'accès aux classes d'amorçage Java, incluez les fichiers SDK nécessaires à l'exécution de vos applications.

Pour vous assurer qu'une bibliothèque JNI exporte les fonctions qu'une application Java doit résoudre lors de l'exécution, vous pouvez examiner la bibliothèque à l'aide de l'outil dumpbin.exe (généralement une partie de l'installation du SDK VC++). Par exemple, la bibliothèque JNI jnitest.dll qui contient les routines JNI fooImpl et barImpl doit exporter les symboles suivants :
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
...

Pour plus d'informations sur dumpbin.exe et ses options, voir la documentation MSDN.

Vous pouvez stocker les méthodes natives comme suit :
Bibliothèques de liaison dynamique
Sous Windows, les méthodes JNI sont généralement stockées dans des bibliothèques dynamiques appelées DLL (Dynamic Link Libraries). Les DLL contiennent des fonctions, et parfois des données, qui peuvent être référencées en dehors de la bibliothèque, par exemple, depuis une bibliothèque dynamique ou un programme exécutable. Les méthodes natives sont stockées dans des DLL et sont liées lors de la génération, via le processus de liaison, ou lors de l'exécution, en chargeant dynamiquement les méthodes à l'aide des fonctions LoadLibrary() et LoadLibraryEx() de l'API Windows. Pour plus d'informations sur la famille de fonctions LoadLibrary(), référez-vous à la documentation MSDN.
Remarque: Pour vous assurer que la liaison dynamique des bibliothèques natives fonctionne correctement, vous pouvez, en option, implémenter les fonctions de cycle de vie JNI_Onload() et JNI_OnUnload() dans la bibliothèque. Si vous avez implémenté JNI_Onload(), la bibliothèque native doit l'exporter. Autrement, elle n'est pas visible par l'exécution et la JVM suppose alors que la bibliothèque a seulement besoin de la version JNI JNI_VERSION_1.1. Si la fonction JNI_OnUnload() a été implémentée, elle doit être exportée. Si JNI_Onload() est implémentée et exportée, la dernière version de JNI est retournée ; par exemple, JNI_VERSION_1.8.

Liaison statique dans Windows

Vous pouvez lier statiquement le programme à des bibliothèques JNI, en plus de le lier dynamiquement. Les bibliothèques statiques peuvent être combinées dans l'image d'un lanceur personnalisé qui lance un processus de JVM en utilisant les API Invocation.

Supposez les deux bibliothèques statiques testlibA et testlibB. Si vous tentez de charger la bibliothèque testlibA dans le programme Java en utilisant une commande telle que System.loadLibrary("testlibA"), la JVM recherche d'abord dans l'image du programme exécutable de lancement une routine nommée JNI_OnLoad_testlibA( ). Si cette routine est trouvée, la JVM utilise cette bibliothèque liée statiquement pour fournir des définitions JNI. Si la routine n'est pas trouvée, la JVM charge dynamiquement la bibliothèque testlibA (par exemple, testlibA.dll) en examinant les chemins spécifiés par -Djava.library.path (ou PATH).

Windows n'impose pas d'options spéciales à spécifier lors de la génération d'un programme exécutable de lanceur.

La routine d'initialisation de la bibliothèque JNI_OnLoad_L, pour une bibliothèque L, doit renvoyerJNI_VERSION_1_8(0x00010008).

Informations spécifiques aux systèmes z/OS

Si la liaison à l'exécution génère un conflit de symboles, vous devez soit le résoudre en renommant le symbole côté application, soit désactiver la liaison à l'exécution.

Liaison dynamique dans z/OS

Lorsque vous générez un programme C ou C++ qui utilise l'API JNI Invocation pour créer une machine virtuelle Java et appelle du code Java, utilisez l'option -L pour effectuer les tâches suivantes:

  • Ajoutez /usr/lib et /lib à la liste des répertoires qui sont recherchés pour les objets partagés. Tous les programmes nécessitent les objets partagés stockés dans ces répertoires.
  • Ajoutez vos répertoires Java java_install_dir/jre/lib et java_install_dir/jre/lib/j9vm à la liste des répertoires dans lesquels sont recherchés les objets partagés. Ces répertoires contiennent les bibliothèques partagées Java. Vous devez également lier votre programme à libjvm.so (en utilisant l'option -ljvm).

Par exemple, ce code génère un programme de lancement d'API d'appel nommé invAPITest en compilant le programme 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

La valeur -q32 ou -q64 indique le modèle de données dans lequel le programme est généré. Si vous omettez ces valeurs, le modèle de données par défaut est utilisé.

Lorsque vous exécutez un programme C ou C++ qui utilise l'API JNI Invocation pour exécuter des classes Java, vérifiez que le chemin d'accès aux classes est configuré correctement pour permettre à la machine virtuelle Java de trouver vos fichiers de classe. Si vous modifiez le chemin d'accès aux classes d'amorçage Java, incluez les fichiers SDK nécessaires à l'exécution de vos applications.

Pour vous assurer qu'une bibliothèque JNI exporte les fonctions qu'une application Java doit résoudre lors de l'exécution, vous pouvez examiner la bibliothèque à l'aide de l'outil nm . Par exemple, la bibliothèque JNI libjnitest.so qui contient les routines JNI fooImpl et barImpl doit exporter les symboles suivants :

$nm libjnitest.so
     255552 T Java_mypackage_SampleClass_fooImpl
     255528 T Java_mypackage_SampleClass_barImpl

Pour plus d'informations, voir Valeurs par défaut des options de compilation.

Vous pouvez stocker les méthodes natives comme suit :
Bibliothèques de liaison dynamique
Sur les systèmes IBM Z® , les méthodes JNI sont généralement stockées dans des bibliothèques dynamiques appelées DLL (Dynamic Link Libraries). Les DLL contiennent des fonctions, et parfois des données, qui peuvent être référencées en dehors de la bibliothèque, par exemple, depuis une bibliothèque dynamique ou un programme exécutable. Les méthodes natives sont stockées dans des DLL et sont liées lors de la génération, via le processus de liaison, ou lors de l'exécution, en chargeant dynamiquement les méthodes à l'aide de l' IBM Z dllload ou de l' POSIX dlopen. Pour plus d'informations sur les fonctions dllload () et dlopen (), voir Chargement d'une DLL.

Les programmes peuvent également se lier dynamiquement à des bibliothèques partagées et des objets partagés, par exemple, en utilisant les familles de sous-routines dlopen() ou dllload(). La JVM se lie de cette façon lorsqu'elle charge des bibliothèques natives (par exemple System.load(), System.loadLibrary(), Runtime.getRuntime().load(), Runtime.getRuntime().loadLibrary()).

Pour plus d'informations sur ces sous-routines, voir dlopen () et dllload ().

Remarque: Pour vous assurer que la liaison dynamique des bibliothèques natives fonctionne correctement, vous pouvez, en option, implémenter les fonctions de cycle de vie JNI_Onload() et JNI_OnUnload() dans la bibliothèque. Si vous avez implémenté JNI_Onload(), la bibliothèque native doit l'exporter. Autrement, elle n'est pas visible par l'exécution et la JVM suppose alors que la bibliothèque a seulement besoin de la version JNI JNI_VERSION_1.1. Si la fonction JNI_OnUnload() a été implémentée, elle doit être exportée. Si JNI_Onload() est implémentée et exportée, la dernière version de JNI est retournée ; par exemple, JNI_VERSION_1.8.

Liaison statique dans z/OS

Vous pouvez lier statiquement le programme à des bibliothèques JNI, en plus de le lier dynamiquement. Les bibliothèques statiques peuvent être combinées dans l'image d'un lanceur personnalisé qui lance un processus de JVM en utilisant les API Invocation.

Supposez les deux bibliothèques statiques testlibA et testlibB. Si vous tentez de charger la bibliothèque testlibA dans le programme Java en utilisant une commande telle que System.loadLibrary("testlibA"), la JVM recherche d'abord dans l'image du programme exécutable de lancement une routine nommée JNI_OnLoad_testlibA( ). Si cette routine est trouvée, la JVM utilise cette bibliothèque liée statiquement pour fournir des définitions JNI. Si la routine n'est pas trouvée, la JVM charge dynamiquement la bibliothèque testlibA (par exemple, libtestlibA.so) en examinant les chemins spécifiés par -Djava.library.path (ou LIBPATH).

Sur les systèmes IBM Z , vous devez spécifier les options suivantes lors de la génération:
  • Wc,DLL, pour vous assurer que le programme exécutable est généré en tant que DLL
  • Wc,EXPORTALL, pour s'assurer que les symboles du programme exécutable sont exportés et mis à disposition pour la recherche par les bibliothèques partagées que le programme charge
Ces options permettent au programme exécutable de lancement d'exporter les symboles (tels que JNI_Onload_testlibA()) pour que la JVM puisse les consulter avant de tenter la liaison dynamique.
L'exemple suivant utilise des lignes de compilation et de liaison pour que les bibliothèques statiques testlibA et testlibB soient liées avec le lanceur qui a été généré comme DLL, et exporte tous les symboles.
cc -c -Wc,DLL,EXPORTALL launcher.c -o launcher.o
cc testlibA.o testlibB.o launcher.o -o launcher

Vous pouvez également supprimer EXPORTALL. Dans ce cas le programme exporte des symboles spécifiques à l'aide de #pragma export. Pour plus d'informations, voir #pragma export.

Remarque: Sur les systèmes IBM Z , un programme exécutable doit être généré en tant que DLL (Dynamic Link Library) en plus des symboles d'exportation, si un programme exécutable regroupe des routines JNI auxquelles le programme Java doit faire référence, à l'aide d'une liaison statique. Si un programme exécutable IBM Z définit et exporte JNI_OnLoad_testlibA, mais qu'il n'est pas lui-même généré en tant que DLL (c'est-à-dire que -Wc,DLL n'est pas spécifié), la liaison statique risque d'échouer car l'exécution ne peut pas résoudre le symbole à partir du programme exécutable.

La routine d'initialisation de la bibliothèque JNI_OnLoad_L, pour une bibliothèque L, doit renvoyerJNI_VERSION_1_8(0x00010008).