Système.loadLibrary ne fonctionne pas. UnsatisfiedLinkError pour la deuxième lib dans la chaîne d'
J'ai un programme en java Client.class qui utilise rpc bibliothèque partagée libclient.donc via JNI.
libclient.ainsi est construit, partagé et utilise rpc bibliothèque partagée libhttp..
libclient.donc, et libhttp.ainsi sont placés dans le dossier /home/client/lib64
Client.class est placé dans /home/client/bin
Client peut charger la bibliothèque avec
- Système.de la charge et de la variable d'environnement LD_LIBRARY_PATH
- Système.loadLibrary et -Djava.de la bibliothèque.chemin
La première méthode fonctionne très bien.
export LD_LIBRARY_PATH = /home/client/lib64
java -classpath ./bin Client
La seconde façon échoue.
java -classpath ./bin -Djava.library.path=./../lib64 Client
java.lang.UnsatisfiedLinkError: /home/client/lib64/libclient.so: libhttp.so: cannot open shared object file: No such file or directory
Quand j'ai mis libhttp.donc dans /usr/lib64 la deuxième façon fonctionne très bien.
Pourquoi libclient.donc, est à la recherche d'libhttp.donc dans /usr/lib64 si j'utilise du Système.loadLibrary?
Comment puis-je résoudre ce problème sans faire face libhttp.donc dans /usr/lib64?
Mon code de chargement:
//Try load from -Djava.library.path
boolean found = false;
String lib = "client";
try {
System.loadLibrary(lib);
found = true;
} catch (UnsatisfiedLinkError e) {
e.printStackTrace();
}
//Try load from LD_LIBRARY_PATH
if (!found) {
lib = "libclient.so";
String ld_lib_path = System.getenv("LD_LIBRARY_PATH");
String[] paths = ld_lib_path.split(":");
for(int i=0; i<paths.length; i++) {
String p = paths[i];
File x = new File(p, lib);
if (x.exists()) {
System.load(x.getAbsolutePath());
found = true;
break;
}
}
}
Des informations supplémentaires.
Si je test libclient.donc, avec ldd puis je vois: libhttp.donc => pas trouvé
Si j'ai mis export LD_LIBRARY_PATH = /home/client/lib64 puis je vois: libhttp.donc => /home/client/lib64/libhttp.donc
OriginalL'auteur degratnik | 2013-04-25
Vous devez vous connecter pour publier un commentaire.
La raison pour cela est que libclient.donc, est chargé à partir de votre JVM, qui regarde dans
java.library.path
. Toutefois, lorsque libclient.donc essaie de charger libhttp.donc, il ne sait rien à propos de Java et utilise juste le régulier Linux le mode de chargement des bibliothèques partagées (l'éditeur de liens dynamiqueld.so
), qui ressemble àLD_LIBRARY_PATH
et certains des répertoires communs comme/usr/lib64
.J'irais probablement avec l'aide de
LD_LIBRARY_PATH
définie à partir d'un script de démarrage de votre application Java. Si vous ne souhaitez pas utiliser un script de démarrage, vous pourriez en théorie définirLD_LIBRARY_PATH
de l'intérieur le processus lui-même. Cependant, Java ne permet pas de le faire (il y a seulementSystem.getenv()
, pasSystem.setenv()
), de sorte que vous devez écrire une petite bibliothèque C qui est appelée à partir de Java et des appelsputenv()
réglageLD_LIBRARY_PATH
.Si vous construisez
libclient.so
lui-même, vous pouvez utiliser le-rpath
de l'éditeur de liens drapeau pour indiquer un chemin où l'éditeur de liens dynamique devrait rechercher d'autres bibliothèques requises. Soyez prudent si vous spécifiez un chemin d'accès relatif ici, il est interprété relativement au répertoire de travail courant de l'application en cours d'exécution, et non pas par rapport à l'emplacement delibclient.so
. Pour ce faire, vous devez utiliser$ORIGIN
comme argument pour-rpath
et veillez à ce que votre shell ne peut pas développer cela.Donc, si vous voulez avoir
libclient.so
etlibhttp.so
dans le même répertoire, vous devez utiliserl'argument de l'éditeur de liens lors de la construction de
libclient.so
. Si vous n'appelez pas le linker directement, mais laissez votre compilateur appel, vous devez ajouter les lignes suivantes à votre ligne de commande du compilateur:Plus d'informations à ce sujet peuvent être trouvées dans le la page de manuel de
ld.so
.OriginalL'auteur Philipp Wendler
Je n'ai pas de bonne réponse à cette question.
Mais j'ai trouvé plusieurs bonnes manières.
OriginalL'auteur degratnik
Pour corriger de recherche de la bibliothèque (à partir de java.de la bibliothèque.chemin) pour les différents OS doivent avoir des noms différents:
Que vous pouvez appeler à partir de Java:
OriginalL'auteur Alexander C.