JNI “symbol lookup error” dans la bibliothèque partagée sur Linux
Que faites-vous quand la machine virtuelle Java a un “symbol lookup error” lors de l'exécution d'une fonction JNI? La recherche de symbole d'erreur n'est pas dans le primaire partagée la bibliothèque d'objets qui prennent en charge l'interface JNI, ni est-il directement au sein d'une bibliothèque liée à l'objet principal de la bibliothèque, mais dans une bibliothèque liée à une bibliothèque liée à votre JNI objet partagé? (ce qui est incroyablement maladroit phrase ☺) en Particulier, que faites-vous quand vous ne contrôlez pas le code de la bibliothèque qui contient le symbole de la délinquance?
J'ai un problème en utilisant JNI pour accéder au kit de développement logiciel pour une caméra scientifique (Andor NÉO CMOS). J'utilise Netbeans C/C++ plugin sur RHEL 6 pour créer une bibliothèque partagée (AndorC.afin) que, fondamentalement, crée JNI wrappers autour des méthodes fournies par les caméras SDK. La caméra SDK fournit un ensemble de méthodes pour accéder à la caméra, qui sont emballés dans un objet partagé de la bibliothèque (libatcore.donc). Le libatcore.donc, la bibliothèque utilise une série de bibliothèques supplémentaires, libatdevregcam.donc (pour la caméra réelle), libatdevsimcam.donc (pour la caméra simulée), libatcl_bitflow.(faible niveau de la carte vidéo pilote), etc. .
J'ai testé l'appareil photo SDK largement et je peux accéder à l'appareil photo sans difficulté à partir de C/C++. J'ai lié à la bibliothèque partagée (AndorC) qui implémente la JNI de fonctions à partir d'un test de programme C (en utilisant un fichier d'en-tête) et tout fonctionne correctement (c'est à dire que je peux lire une image et le programme se termine normalement).
Mon code Java peut exécuter le “InitializeLibrary” et “FinalizeLibrary” les fonctions du SDK par le biais de l'interface JNI, donc il n'y a aucun problème pour trouver le primaire libatcore.donc, bibliothèque ou mon AndorC.si la bibliothèque. Il ne semble pas y avoir de problème avec la configuration de base de la JNI. Cependant, lorsque j'essaie d'exécuter la fonction “Ouvrir” pour l'appareil photo (c'est à dire la fonction qui connecte les réelles et/ou simulées, appareil photo), je reçois un symbole non défini erreur dans l'une des bibliothèques de la libatcore.ainsi, les bibliothèques utilise au moment de l'exécution (libdevsimcam.donc).
/usr/local/java/jdk1.7.0_03/jre/bin/java: symbol lookup error: /usr/local/lib/libatdevsimcam.so: undefined symbol: _ZN20TAndorLibDebugOutput6OutputEPKciS1_xx24TAndorDebugFunctionLevel16TAndorDebugLevelS1_z
Java Result: 127
Essentiellement, la machine virtuelle Java n'a pas un problème avec le libatcore.donc (c'est à dire le principal fichier de bibliothèque) et il n'a pas un problème de la localisation de l'associé de la bibliothèque d'exécution (/usr/local/lib/libatdevsimcam.façon), mais il s'agit d'un symbole non défini dans la bibliothèque quand il essaie d'ouvrir l'appareil photo (notez que je suis en fait à l'ouverture de la caméra réelle PAS la caméra simulée).
Quand j'ai vérifié les dépendances sur chacune des bibliothèques (libAndorC.donc, libatcore.donc, libatdevsimcam.ainsi), je ne trouve pas les symboles non définis. Évidemment, le symbole non défini dans la libatdevsimcam.si la bibliothèque n'est pas un problème lorsque le programme est exécuté directement à partir de C/C++, mais elle provoque un problème lorsque la machine virtuelle Java essaie de charger libatdevsimcam..
libAndorC.so
linux-vdso.so.1 => (0x00007fff507ff000)
libatcore.so.3 => /usr/local/lib/libatcore.so.3 (0x00007fe23a278000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fe239f4a000)
libm.so.6 => /lib64/libm.so.6 (0x00007fe239cc6000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe239ab0000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe239730000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe239513000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe23930f000)
librt.so.1 => /lib64/librt.so.1 (0x00007fe239106000)
/lib64/ld-linux-x86-64.so.2 (0x0000003f07000000)
libatcore.so
linux-vdso.so.1 => (0x00007fffd53ff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7e6b645000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f7e6b440000)
librt.so.1 => /lib64/librt.so.1 (0x00007f7e6b238000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f7e6af31000)
libm.so.6 => /lib64/libm.so.6 (0x00007f7e6acac000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f7e6aa96000)
libc.so.6 => /lib64/libc.so.6 (0x00007f7e6a717000)
/lib64/ld-linux-x86-64.so.2 (0x0000003f07000000)
ldd libatdevsimcam.so
linux-vdso.so.1 => (0x00007fff247ef000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5219dc4000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f5219bbf000)
librt.so.1 => /lib64/librt.so.1 (0x00007f52199b7000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f52196b0000)
libm.so.6 => /lib64/libm.so.6 (0x00007f521942b000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f5219215000)
libc.so.6 => /lib64/libc.so.6 (0x00007f5218e96000)
/lib64/ld-linux-x86-64.so.2 (0x0000003f07000000)
Quand j'ai spécifiquement vérifier que le symbole que la machine virtuelle Java est d'avoir un problème avec, il est clair que le symbole n'est pas défini.
nm libatdevsimcam.so | grep _ZN20TAndor
U _ZN20TAndorLibDebugOutput6OutputEPKciS1_xx24TAndorDebugFunctionLevel16TAndorDebugLevelS1_z
J'ai pensé que peut-être le symbole n'était pas défini dans la version vs version de débogage de l'libatdevsimcam.donc, bibliothèque, j'ai donc essayé de construire une version de la libAndorC.mais j'ai eu le même problème.
J'ai deux questions de base
- - Ce que cela pourrait être un problème avec C++ name mangling? J'ai essayé de compiler mon programme de test de la caméra avec gcc au lieu de g++ et je cours dans un grand nombre d'erreurs de compilation. J'ai lu que C++ name mangling peut causer des problèmes.
- Est-ce un problème dans le libatdevsimcam.donc, bibliothèque fournie par le fabricant? Je n'ai pas de contrôle sur le code fourni par Andor à l'appui de l'appareil photo (tout ce que je peux faire est de se plaindre).
Je suis tout bonnement à ce point parce que tous les SDK fonctions nécessitent une référence à l'appareil photo de la poignée renvoyée par la méthode “Open”. Si je ne peux pas ouvrir l'appareil photo je ne peux pas procéder à l'élaboration de la JNI de l'interface de l'appareil photo dont j'ai besoin.
J'ai des recherches à cette question de manière approfondie et je n'ai pas trouvé toutes les réponses qui abordent directement la question. Ce n'est pas la norme “insatisfaits lien” erreur si répandue dans JNI-postes de base JNI fonctionnalité semble fonctionner (c'est à dire que vous pouvez initialiser et de finaliser la bibliothèque ou appel une fonction qui n'est pas directement accéder à l'appareil photo) . Cela semble être une situation où la machine virtuelle Java se heurte à un problème avec le code natif simplement en exécutant directement le code ne produit pas. Comment faites-vous face à ce genre de problème? Est-ce un problème j'ai besoin de prendre du fabricant ou est-il une configuration /compilation /méthode de mise en relation de traiter cette question?
Quelques détails supplémentaires:
- Netbeans 6.9.1 environnement de développement
- JDK 1.7_0_03 64 bits, serveur
- De la compilation de sources de 64 bits (c'est à dire il ne devrait pas être 32 vs 64 bits problèmes)
OriginalL'auteur Jennifer Milburn | 2012-03-04
Vous devez vous connecter pour publier un commentaire.
Vous pouvez vous en débarrasser en utilisant LD_PRELOAD (mais je ne pense pas que ce soit une bonne solution)
L'Histoire
J'ai été confrontée au même problème, et mon scénario est...
*javaHelloWorldApp.java --> JNI_Hello_world.c --> ce natif c les appels de la fonction snmp bibliothèque*
java: symbol lookup error: /home/source/bin/libmytest.so: undefined symbol: init_snmp
J'ai utilisé LD_PRELOAD comme le montre ici et résout le problème pour l'instant.
export LD_PRELOAD=/usr/local/lib/libnetsnmp.so.30
Question Ouverte
ldd donne, (remarque, il n'y a aucune référence à snmp bibliothèque)
avec
export LD_PRELOAD=/usr/local/lib/libnetsnmp.so.30
je voir les références aux snmp,snmp$ldd ../libredsnmp/bin/libredsnmp.donc
ma ligne de compilation,
gcc -fPIC -shared -o ./bin/libmytest.so -I/usr/lib/jvm/java-6-openjdk-i386/include/-I/usr/lib/jvm/java-6-openjdk-i386/include/linux -static -lc JNI_Hello_world.c
D'autres options que j'ai essayé,
-L/usr/local/lib -lnetsnmp
, ne pas avoir d'effet si je l'ai enlevé de la compilation.EDIT-1
obtenu il a travaillé avec ces deux commandes, et aucune autre variable d'environnement,
Tout d'abord, compiler le source
Maintenant, utilisez -rpath linker option lors de la construction de la bibliothèque partagée.
Pour Les Références Détaillées
Pour une description détaillée, reportez-vous à cette livre (ou tout simplement cette recherche de livres de google résultat, @ ch.41.10)
L'-l<libname> au cours de la liaison a fonctionné pour moi! Génial! Ajoutez à cela
Linker Flags
sousMiscellaneous
partie deGCC C Linker
si vous utilisez Eclipse sous LinuxOriginalL'auteur tsenapathy
J'ai eu le même problème, et plus tard, j'ai trouvé que c'était le problème de la liaison entre l'ordre:
vous avez besoin de mettre
-L/usr/local/lib -lnetsnmp
après la-o libmytest.so
pour que cela fonctionne.C'était vraiment elle. Dans le cas où quelqu'un est à l'aide de nar-maven-plugin, utilisez l'éditeur de liens
<libs>
tag au lieu de spécifier les bibliothèques dans<options>
. Ce qui les met dans le bon ordre.OriginalL'auteur tudali0928