Java.lang.UnsatisfiedLinkError non******.dll en java.bibliothèque.chemin

Comment puis-je charger un fichier dll personnalisé dans mon application web? J'ai essayé de suivre des chemins mais ça a échoué.

  • copié tous les dlls requis dans le dossier system32 et essayé de charger l'un d'eux dans Servlet constructeur System.loadLibrary
  • copié dlls requis dans tomcat_home/shared/lib et tomcat_home/common/lib
  • tous ces dlls sont dans WEB-INF/lib de l'application web
81
demandé sur Adam Batkin 2009-09-10 11:19:00

12 réponses

pour que System.loadLibrary() fonctionne, la bibliothèque (sur Windows, une DLL) doit être dans un répertoire quelque part sur votre PATH ou sur un chemin répertorié dans la propriété du système java.library.path (donc vous pouvez lancer Java comme java -Djava.library.path=/path/to/dir ).

de plus, 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 juste System.loadLibrary("something") .

Vous devez également regarder l'exacte UnsatisfiedLinkError que vous obtenez. Si elle dit quelque chose comme:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path

, alors il ne peut pas trouver le foo de la bibliothèque (foo.dll) dans votre PATH ou java.library.path . Si elle 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 dans le sens où Java n'est pas capable de mapper une fonction Java native dans votre application à son équivalent natif réel.

pour commencer, je mettrais un peu de journalisation autour de votre appel System.loadLibrary() pour voir si cela s'exécute correctement. Si elle lance une exception ou n'est pas dans un chemin de code qui est effectivement exécuté, alors vous obtiendrez toujours le dernier type de UnsatisfiedLinkError expliqué ci-dessus.

comme un sidenote, la plupart des gens mettent leurs appels loadLibrary() dans un bloc initialiseur statique dans 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() {
    }

}
135
répondu Adam Batkin 2009-09-10 07:33:09

la réponse originale par Adam Batkin vous mènera à une solution, mais si vous redéployez votre webapp (sans redémarrer votre conteneur web), vous devriez courir dans l'erreur suivante:

java.lang.UnsatisfiedLinkError: Native Library "foo" already loaded in another classloader
   at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1715)
   at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1646)
   at java.lang.Runtime.load0(Runtime.java:787)
   at java.lang.System.load(System.java:1022)

cela se produit parce que le ClassLoader qui a chargé à l'Origine votre DLL fait toujours référence à cette DLL. Cependant, votre webapp est maintenant en cours d'exécution avec un nouveau ClassLoader, et parce que la même JVM est en cours d'exécution et une JVM ne permettra pas 2 références à la même DLL, vous ne pouvez pas recharger . Ainsi, votre webapp ne peut pas accéder à la DLL existante et ne peut pas charger une nouvelle DLL. Si.... vous êtes coincé.

la documentation ClassLoader de Tomcat explique pourquoi votre webapp rechargée fonctionne 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:

   package awesome;

   public class Foo {

        static {
            System.loadLibrary('foo');
        }

        // required to work with JDK 6 and JDK 7
        public static void main(String[] args) {
        }

    }

alors placer un jar contenant juste cette classe compilée dans le dossier TOMCAT_HOME/lib.

maintenant, dans votre webapp, vous avez juste à forcer Tomcat de référence cette classe, qui peut être fait aussi simplement que ceci:

  Class.forName("awesome.Foo");

maintenant votre DLL doit être chargé dans le classloader commun, et peut être référencé à partir de votre webapp même après avoir été redéployé.

ça a un sens?

une copie de référence de travail peut être trouvée sur le code google, static-dll-bootstrapper .

10
répondu Matt M 2012-11-06 14:45:54

une " Modification de la java.bibliothèque.la variable path' à l'exécution n'est pas suffisante car elle n'est lue qu'une seule fois par JVM. Vous devez le réinitialiser comme:

System.setProperty("java.library.path", path);
//set sys_paths to null
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);

s'il vous Plaît, prendre un butin à: Changement de Java Chemin de la Bibliothèque au moment de l'Exécution .

10
répondu Alexandre 2014-02-12 14:01:56

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 la 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 votre propre, vous êtes probablement mieux avec load().

vous devriez également pouvoir utiliser loadLibrary avec le java.library.path réglé correctement. Voir ClassLoader.java pour la mise en œuvre de la source montrant à la fois les chemins d'accès en cours de vérification (OpenJDK)

6
répondu Philip Whitehouse 2012-10-19 21:41:00

dans le cas où le problème est ce système.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é du système java.bibliothèque.chemin d'accès est la réponse. Si vous définissez la propriété système java.bibliothèque.chemin vers le répertoire où se trouve votre DLL, puis Système.loadLibrary trouvera bien votre DLL. Cependant, si votre DLL dépend à son tour d'autres DLLs, comme c'est souvent le cas, alors java.bibliothèque.chemin ne peut pas aider, parce que le le chargement des DLLs dépendants est géré entièrement par le système d'exploitation, qui ne connaît rien de java.bibliothèque.chemin. Ainsi, il est presque toujours préférable de contourner java.bibliothèque.path et ajoutez simplement le répertoire de votre DLL à LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS), ou Path (Windows) avant de lancer le JVM.

(Note: j'utilise le terme" DLL " dans le sens générique de DLL ou de bibliothèque partagée.)

4
répondu Ian Emmons 2014-01-17 15:33:33

pour ceux qui cherchent java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path

je faisais face à la même exception; j'ai tout essayé et les choses importantes pour le faire fonctionner sont:

  1. version correcte de pdf lib.pot ( Dans mon cas c'était une mauvaise version jar conservés dans server runtime )
  2. créer un dossier et y conserver le pot pdflib et ajouter le dossier dans votre variable PATH

il a travaillé avec tomcat 6.

2
répondu Mangesh M. Kulkarni 2012-09-28 07:48:06

pauvre moi ! passé une journée entière derrière tout cela.Notez-le ici si un corps reproduit ce problème.

J'essayais de charger comme Adam l'a suggéré, mais j'ai été pris avec AMD64 vs IA 32 exception.Si,dans tous les cas, après avoir travaillé comme Adam(sans doute le meilleur choix) walkthrough, essayer d'avoir une version 64 bits de la dernière jre.Assurez-vous que votre JRE et JDK sont 64 bits et que vous l'avez correctement ajouté à votre classpath.

mon exemple de travail va ici: unsatisfied link error

2
répondu sayannayas 2012-10-19 21:07:35

si vous avez besoin de charger un fichier relatif à un répertoire où vous êtes déjà (comme dans le répertoire courant), voici une solution simple:

File f;

if (System.getProperty("sun.arch.data.model").equals("32")) {
    // 32-bit JVM
    f = new File("mylibfile32.so");
} else {
    // 64-bit JVM
    f = new File("mylibfile64.so");
}
System.load(f.getAbsolutePath());
2
répondu Rick C. Hodgin 2013-07-13 17:40:13

Pour windows j'ai constaté que lorsque j'ai chargé les filles(jd2xsx.dll appels & ftd2xx.dll) dans le dossier windowws/system32, les problèmes ont été résolus. J'ai ensuite eu un problème avec mon nouveau fd2xx.dll c'est à cause des paramètres que j'ai dû charger l'ancienne version de cette dll. Je vais devoir le déballer plus tard.

Remarque: la jd2xsx.la dll appelle ftd2xx.dll donc, il suffit de définir le chemin pour le jd2xx.dll ça ne marchera peut-être pas.

0
répondu Dan Carte 2014-03-06 20:37:03

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, c'est utile quand vous avez besoin d'inclure la bibliothèque native dans le projet. Comme la suivante pour Netbeans:

1.- Right click on the Project
2.- Properties
3.- Click on RUN
4.- VM Options: java -Djava.library.path="your_path"
5.- for example in my case: java -Djava.library.path=</Users/Lexynux/NetBeansProjects/NAO/libs>
6.- Ok

j'espère qu'elle pourra être utile pour quelqu'un. Le lien où j'ai trouvé la solution est ici: de java.bibliothèque.chemin – Ce que c'est et comment l'utiliser

0
répondu Alex Ventura 2015-03-31 02:47:44

j'ai eu le même problème et l'erreur était due à un changement de nom de la dll. Il peut arriver que le nom de la bibliothèque soit aussi écrit quelque part à l'intérieur de la dll. Quand j'ai remis son nom d'origine, j'ai été capable de charger en utilisant System.loadLibrary

0
répondu Alessandro Marini 2018-10-04 12:50:51
This is My java.library.path:

 java.library.path = C:\Program Files\Java\jdk1.7.0_51\bin
     C:\WINDOWS\Sun\Java\bin
     C:\WINDOWS\system32
     C:\WINDOWS
     C:\WINDOWS\system32
     C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskr
.lib
     C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSG
idgeDll.dll
     C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSG
aderDll.dll
     C:\Program Files\Java\jdk1.7.0_51\bin
     C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include
     C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib
     C:\WINDOWS\System32\Wbem
     C:\WINDOWS\System32\WindowsPowerShell\v1.0
     C:\Program Files (x86)\Microsoft SQL Server0\Tools\Binn\
     C:\Program Files\Microsoft SQL Server0\DTS\Binn

Still rror comes: 
infile >> D:\pdf_upload\pre_idrs15_win_temporary_license_activation_tutorial.pdf
outFile >> D:\pdf_upload\processed\pre_idrs15_win_temporary_license_activation_tutorial.txt
Hello : This is java library path:(NICKRJ) C:\Program Files\Java\jdk1.7.0_51\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jdk1.7.0_51/jre/bin/server;C:/Program Files/Java/jdk1.7.0_51/jre/bin;C:/Program Files/Java/jdk1.7.0_51/jre/lib/amd64;C:\WINDOWS\system32;C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskrn15.lib;C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEBridgeDll.dll;C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEReaderDll.dll;C:\Program Files\Java\jdk1.7.0_51\bin;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\Microsoft SQL Server0\Tools\Binn\;C:\Program Files\Microsoft SQL Server0\DTS\Binn;D:\WorkSet\New folder\eclipse_kepler\eclipse;;.
Exception in thread "main" java.lang.UnsatisfiedLinkError: no iDRMSGEBridgeDll in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
    at java.lang.Runtime.loadLibrary0(Runtime.java:849)
    at java.lang.System.loadLibrary(System.java:1088)
    at com.bi.iDRMSGEBridgeDll.callOcr(iDRMSGEBridgeDll.java:78)
    at com.bi.iDRMSGEBridgeDll.main(iDRMSGEBridgeDll.java:15)


Here is my Java JNI class:

package com.bi;

import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;

public class iDRMSGEBridgeDll  
{
  public native int iDRMSGEDll_Initialize(String strPropertiesFileName);
  public native int iDRMSGEDll_VerifyLicense();
  public native int iDRMSGEDll_ConvertFile(String strSourceFileName, String srcOutputFileName,  String formatType);
  public native int iDRMSGEDll_Finalize();

public static void main(String[] args)
{
    //iDRMSGEBridgeDll.callOcr("bgimage.jpg","jpg","","d:\","d:\","4");
    iDRMSGEBridgeDll.callOcr("pre_idrs15_win_temporary_license_activation_tutorial.pdf","pdf","","D:\pdf_upload","D:\pdf_upload\processed","4");


    /*  System.loadLibrary("iDRMSGEBridgeDll");
        iDRMSGEBridgeDll obj = new iDRMSGEBridgeDll();
        if ( obj.iDRMSGEDll_Initialize("D:\iris\iDRSGEDll.properties") != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_Initialize success.");
        if ( obj.iDRMSGEDll_VerifyLicense() != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_VerifyLicense success.");
        if (obj.iDRMSGEDll_ConvertFile("E:\UI changes File_by Shakti\PDF\S14-005_FRAMEWORK_AGREEMENT_FOR_ENGINE_MAINTENANCE_SERVICES_EASYJET[1].pdf", 
            "E:\SK_Converted_Files\MVP_CONTRACTS\Southwest CFM56-7\S14-005_FRAMEWORK_AGREEMENT_FOR_ENGINE_MAINTENANCE_SERVICES_EASYJET[1]\S14-005_FRAMEWORK_AGREEMENT_FOR_ENGINE_MAINTENANCE_SERVICES_EASYJET[1].txt", "4" ) != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_ConvertFile 1 success.");
        /*if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_200dpi.pdf", 
            "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_200dpi.out", 4) != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_ConvertFile 2 success.");
        if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_300dpi.pdf", 
            "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_300dpi.out", 4) != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_ConvertFile 3 success.");
        if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan2_300dpi.pdf", 
            "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan2_300dpi.out", 4) != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_ConvertFile 4 success.");
        obj.iDRMSGEDll_Finalize();
        System.out.println("iDRMSGEDll_Finalize success.");
        return;*/

}
    public static String callOcr(String inputFile, String docType, String engineType, String filePath,String outputFolder,String type) throws RuntimeException
    {
        String message =  "";
        String formatType = type;           
        String inFile = filePath +"\" +inputFile;
        String outFile="";
        if(type.equals("4"))
        outFile = outputFolder +"\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".txt";
        else if(type.equals("6"))
            outFile = outputFolder +"\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".rtf";
        else if(type.equals("9"))
            outFile = outputFolder +"\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".pdf";
        else
            outFile = outputFolder +"\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".csv";

        System.out.println("infile >> "+inFile);
        System.out.println("outFile >> "+outFile);
        System.out.println("Hello : This is java library path:(NICKRJ) " +System.getProperty("java.library.path"));

        System.loadLibrary("iDRMSGEBridgeDll");
        //System.load("C:\Program Files (x86)\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEBridgeDll.dll");
        //Runtime.getRuntime().loadLibrary("iDRMSGEBridgeDll");

            iDRMSGEBridgeDll obj = new iDRMSGEBridgeDll();
        try
        {
            if ( obj.iDRMSGEDll_Initialize("D:\IRIS\iDRSGEDll.properties") != 0 ) {
                obj.iDRMSGEDll_Finalize();
            //  return ; 
            }
            System.out.println("iDRMSGEDll_Initialize success.");
            if ( obj.iDRMSGEDll_VerifyLicense() != 0 ) {
                obj.iDRMSGEDll_Finalize();
        //      return;
            }
            System.out.println("iDRMSGEDll_VerifyLicense success.");
        //  formatType= JOptionPane.showInputDialog("Please input mark format type: ");
            if (formatType!=null && formatType.equals("4"))  {
                obj.iDRMSGEDll_ConvertFile(inFile, 
                        outFile, "4" ); 
                obj.iDRMSGEDll_Finalize();
        //      return;
            }
            else if(formatType!=null && formatType.equals("6")) {
                obj.iDRMSGEDll_ConvertFile(inFile, 
                        outFile, "6" ); 
                    obj.iDRMSGEDll_Finalize();
            //      return;
                }   
            else if(formatType!=null && formatType.equals("7")) {
                obj.iDRMSGEDll_ConvertFile(inFile, 
                        outFile, "7" ); 
                    obj.iDRMSGEDll_Finalize();
            //      return;
                }
            else if(formatType!=null && formatType.equals("9")) {
                obj.iDRMSGEDll_ConvertFile(inFile, 
                        outFile, "9" ); 
                    obj.iDRMSGEDll_Finalize();
            //      return;
                }
            else
            {
            message= "iDRMSGEDll_VerifyLicense failure";
            }

            System.out.println("iDRMSGEDll_ConvertFile 1 success.");
            /*if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_200dpi.pdf", 
                "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_200dpi.out", 4) != 0 ) {
                obj.iDRMSGEDll_Finalize();
                return;
            }
            System.out.println("iDRMSGEDll_ConvertFile 2 success.");
            if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_300dpi.pdf", 
                "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_300dpi.out", 4) != 0 ) {
                obj.iDRMSGEDll_Finalize();
                return;
            }
            System.out.println("iDRMSGEDll_ConvertFile 3 success.");
            if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan2_300dpi.pdf", 
                "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan2_300dpi.out", 4) != 0 ) {
                obj.iDRMSGEDll_Finalize();
                return;
            }
            System.out.println("iDRMSGEDll_ConvertFile 4 success.");*/
            obj.iDRMSGEDll_Finalize();
            System.out.println("iDRMSGEDll_Finalize success.");
            if(message.length()==0)
            {
                message = "success";
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
            message = e.getMessage();
        }

        return message;





    }


}
-1
répondu user3364275 2017-06-30 04:16:47