Pour System.loadLibrary()
fonctionner, la bibliothèque (sous Windows, une DLL) doit être dans un répertoire quelque part sur votre PATH
ou sur un chemin répertorié dans la java.library.path
propriété système (vous pouvez donc lancer Java comme java -Djava.library.path=/path/to/dir
).
En outre, pour loadLibrary()
, vous spécifiez le nom de base de la bibliothèque, sans le .dll
à la fin. Donc, pour /path/to/something.dll
, vous utiliseriez simplement System.loadLibrary("something")
.
Vous devez également regarder exactement ce UnsatisfiedLinkError
que vous obtenez. Si cela dit quelque chose comme:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
alors il ne peut pas trouver la bibliothèque foo (foo.dll) dans votre fichier PATH
ou java.library.path
. Si cela dit quelque chose comme:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
alors quelque chose ne va pas avec la bibliothèque elle-même en ce sens que Java n'est pas capable de mapper une fonction Java native de votre application à son homologue natif réel.
Pour commencer, je mettrais un peu de journalisation autour de votre System.loadLibrary()
appel pour voir si cela s'exécute correctement. S'il lève une exception ou n'est pas dans un chemin de code réellement exécuté, vous obtiendrez toujours le dernier type d' UnsatisfiedLinkError
explication ci-dessus.
Pour rappel, la plupart des gens placent leurs loadLibrary()
appels dans un bloc d'initialisation statique de la classe avec les méthodes natives, pour s'assurer qu'il est toujours exécuté exactement une fois:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}
loadLibrary()
remarque - très utile lorsque vous n'avez aucune idée de ce que vous faites mal.lib
préfixe. DoncSystem.loadLibrary("foo")
besoinslibfoo.so
.blah.jnilib
et Linuxlibblah.so
. Eh bien, deux heures plus tard, après de nombreux essais, je suis arrivé à la conclusion qu'OSX nécessite également unlib
préfixeChanger la variable 'java.library.path' lors de l'exécution ne suffit pas car elle n'est lue qu'une seule fois par JVM. Vous devez le réinitialiser comme:
S'il vous plaît, prenez un butin sur: Modification du chemin de la bibliothèque Java au moment de l'exécution .
la source
La réponse originale d'Adam Batkin vous mènera à une solution, mais si vous redéployez votre application Web (sans redémarrer votre conteneur Web), vous devriez rencontrer l'erreur suivante:
Cela se produit car le ClassLoader qui a chargé à l'origine votre DLL fait toujours référence à cette DLL. Cependant, votre application Web est maintenant en cours d'exécution avec un nouveau ClassLoader, et comme la même JVM est en cours d'exécution et qu'une JVM n'autorisera pas 2 références à la même DLL, vous ne pouvez pas la recharger . Ainsi, votre application Web ne peut pas accéder à la DLL existante et ne peut pas en charger une nouvelle. Alors ... vous êtes coincé.
La documentation ClassLoader de Tomcat explique pourquoi votre application Web rechargée s'exécute dans un nouveau ClassLoader isolé et comment vous pouvez contourner cette limitation (à un niveau très élevé).
La solution est d'étendre un peu la solution d'Adam Batkin:
Ensuite, placez un fichier jar contenant JUSTE cette classe compilée dans le dossier TOMCAT_HOME / lib.
Maintenant, dans votre application web, il vous suffit de forcer Tomcat à référencer cette classe, ce qui peut être fait aussi simplement que ceci:
Maintenant, votre DLL doit être chargée dans le chargeur de classe commun et peut être référencée à partir de votre application Web même après avoir été redéployée.
Ça a du sens?
Une copie de référence de travail peut être trouvée sur le code google, static-dll-bootstrapper .
la source
Vous pouvez utiliser
System.load()
pour fournir un chemin absolu qui est ce que vous voulez, plutôt qu'un fichier dans le dossier de bibliothèque standard pour le système d'exploitation respectif.Si vous voulez des applications natives qui existent déjà, utilisez
System.loadLibrary(String filename)
. Si vous voulez fournir le vôtre, vous êtes probablement mieux avec load ().Vous devriez également pouvoir l'utiliser correctement
loadLibrary
avec l'java.library.path
ensemble. Voir laClassLoader.java
source d'implémentation montrant les deux chemins en cours de vérification (OpenJDK)la source
Dans le cas où le problème est que System.loadLibrary ne peut pas trouver la DLL en question, une idée fausse courante (renforcée par le message d'erreur de Java) est que la propriété système java.library.path est la réponse. Si vous définissez la propriété système java.library.path sur le répertoire où se trouve votre DLL, alors System.loadLibrary trouvera effectivement votre DLL. Cependant, si votre DLL dépend à son tour d'autres DLL, comme c'est souvent le cas, alors java.library.path ne peut pas aider, car le chargement des DLL dépendantes est entièrement géré par le système d'exploitation, qui ne sait rien de java.library. chemin. Ainsi, il est presque toujours préférable de contourner java.library.path et d'ajouter simplement le répertoire de votre DLL à LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS) ou Path (Windows) avant de démarrer la JVM.
(Remarque: j'utilise le terme «DLL» dans le sens générique de DLL ou de bibliothèque partagée.)
la source
Si vous devez charger un fichier relatif à un répertoire dans lequel vous vous trouvez déjà (comme dans le répertoire actuel), voici une solution simple:
la source
Pour ceux qui recherchent
java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
J'étais confronté à la même exception; J'ai tout essayé et les choses importantes pour le faire fonctionner sont:
Cela a fonctionné avec tomcat 6.
la source
Si vous pensez avoir ajouté un chemin d'accès à la bibliothèque native
%PATH%
, essayez de tester avec:Il devrait vous montrer si votre dll est activé
%PATH%
%PATH%
la source
Pauvre de moi ! a passé une journée entière derrière cela, écrivez-le ici si un organisme reproduit ce problème.
J'essayais de charger comme Adam l'a suggéré, mais j'ai ensuite été pris avec l'exception AMD64 vs IA 32.Si dans tous les cas, après avoir travaillé selon la procédure pas à pas d'Adam (sans aucun doute le meilleur choix), essayez d'avoir une version 64 bits du dernier jre. vos JRE ET JDK sont 64 bits et vous les avez correctement ajoutés à votre classpath.
Mon exemple de travail va ici: erreur de lien non satisfaite
la source
Pour Windows, j'ai trouvé que lorsque j'ai chargé les filles (appels jd2xsx.dll & ftd2xx.dll) dans le dossier windowws / system32, cela a résolu les problèmes. J'ai ensuite eu un problème avec mon plus récent fd2xx.dll concernant les paramètres, c'est pourquoi j'ai dû charger l'ancienne version de cette dll. Je devrai le découvrir plus tard.
Remarque: le jd2xsx.dll appelle le ftd2xx.dll, il se peut donc que la définition du chemin d'accès pour le jd2xx.dll ne fonctionne pas.
la source
J'utilise Mac OS X Yosemite et Netbeans 8.02, j'ai la même erreur et la solution simple que j'ai trouvée est comme ci-dessus, cela est utile lorsque vous devez inclure une bibliothèque native dans le projet. Alors faites la suite pour Netbeans:
J'espère que cela pourrait être utile pour quelqu'un. Le lien où j'ai trouvé la solution est ici: java.library.path - Qu'est-ce que c'est et comment l'utiliser
la source
VM Options: java -Djava.library.path="your_path"
J'ai eu le même problème et l'erreur était due à un changement de nom de la DLL. Il se peut que le nom de la bibliothèque soit également écrit quelque part dans la DLL. Quand j'ai remis son nom d'origine, j'ai pu charger en utilisant
System.loadLibrary
la source
C'est simple, écrivez simplement java -XshowSettings: properties sur votre ligne de commande dans Windows, puis collez tous les fichiers dans le chemin indiqué par java.library.path.
la source