Frage

Wie kann ich eine benutzerdefinierte DLL -Datei in meine Webanwendung laden? Ich habe versucht, Wege zu folgen, aber es scheitert.

  • kopierte alle erforderlichen DLLs in system32 Ordner und versuchte, einen davon in zu laden Servlet Konstrukteur System.loadLibrary
  • Kopierte die erforderlichen DLLs in tomcat_home/shared/lib und tomcat_home/common/lib
  • Alle diese DLLs sind in WEB-INF/lib der Web-Anwendung
War es hilfreich?

Lösung

Damit System.loadLibrary() Um zu arbeiten, muss die Bibliothek (unter Windows, eine DLL) irgendwo in einem Verzeichnis auf Ihrem sein PATH oder auf einem in der aufgeführten Pfad java.library.path Systemeigenschaft (so können Sie Java mögen wie java -Djava.library.path=/path/to/dir).

Zusätzlich für loadLibrary(), Sie geben den Grundnamen der Bibliothek ohne die an .dll Am Ende. So für /path/to/something.dll, Sie würden einfach benutzen System.loadLibrary("something").

Sie müssen sich auch genau das ansehen UnsatisfiedLinkError dass du bekommst. Wenn es so etwas sagt:

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

Dann kann es das nicht finden Foo Bibliothek (foo.dll) in Ihrem PATH oder java.library.path. Wenn es so etwas sagt:

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V

Dann stimmt etwas mit der Bibliothek selbst nicht in dem Sinne, dass Java eine native Java -Funktion in Ihrer Anwendung nicht auf sein tatsächliches natives Gegenstück abbilden kann.

Zunächst würde ich etwas um Ihre Anmeldung legen System.loadLibrary() Rufen Sie an, um festzustellen, ob dies ordnungsgemäß ausgeführt wird. Wenn es eine Ausnahme ausgelegt hat oder sich nicht in einem tatsächlich ausgeführten Codepfad befindet, erhalten Sie immer die letztere Art von UnsatisfiedLinkError oben erklärt.

Als Nebenkinder setzen die meisten Menschen ihre loadLibrary() Ruft mit den nativen Methoden in einen statischen Initialisiererblock in der Klasse auf, um sicherzustellen, dass er immer genau einmal ausgeführt wird:

class Foo {

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

    public Foo() {
    }

}

Andere Tipps

Ändern von 'java.library.Path' Variable zur Laufzeit reicht nicht aus, da es nur einmal von JVM gelesen wird. Sie müssen es zurücksetzen wie:

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);

Bitte nehmen Sie eine Beute bei: Ändern des Java -Bibliothekspfads zur Laufzeit.

Die ursprüngliche Antwort von Adam Batkin führt Sie zu einer Lösung. Wenn Sie jedoch Ihren WebApp neu einsetzen (ohne Ihren Webcontainer neu zu starten), sollten Sie den folgenden Fehler treffen:

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)

Dies geschieht, weil der Klassenloader, der ursprünglich Ihre DLL geladen hat, diese DLL nach wie vor verweist. Ihr WebApp wird jedoch jetzt mit einem neuen Klassenloader ausgeführt, und da dieselbe JVM ausgeführt wird und ein JVM keine 2 Verweise auf dieselbe DLL erlaubt, können Sie nicht können neu laden es. Daher kann Ihr WebApp nicht auf die vorhandene DLL zugreifen und keine neue laden. Also ... du steckst fest.

Tomcats Klassenloaderdokumentation Umzusetzen, warum Ihr neu geladener WebApp in einem neuen isolierten Klassenloader ausgeführt wird und wie Sie diese Einschränkung (auf einem sehr hohen Niveau) umgehen können.

Die Lösung besteht darin, die Lösung von Adam Batkin ein wenig zu erweitern:

   package awesome;

   public class Foo {

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

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

    }

Dann ein Glas mit dieser kompilierten Klasse in den Ordner tomcat_home/lib.

In Ihrem WebApp müssen Sie nun nur Tomcat dazu zwingen, auf diese Klasse zu verweisen, die so einfach wie folgt durchgeführt werden kann:

  Class.forName("awesome.Foo");

Jetzt sollte Ihre DLL in den gemeinsamen Klassenloader geladen werden und kann auch nach der Neueinstellung aus Ihrem WebApp verwiesen werden.

Sinn ergeben?

Eine funktionierende Referenzkopie finden Sie in Google Code. static-dll-Bootstrapper .

Sie können verwenden System.load() Um einen absoluten Pfad bereitzustellen, der Sie wollen, anstatt eine Datei im Standardbibliotheksordner für das jeweilige Betriebssystem.

Wenn Sie native Anwendungen wünschen, die bereits vorhanden sind, verwenden Sie System.loadLibrary(String filename). Wenn Sie Ihre eigenen zur Verfügung stellen möchten, sind Sie wahrscheinlich besser mit Load ().

Sie sollten auch in der Lage sein zu verwenden loadLibrary mit dem java.library.path richtig einstellen. Sehen ClassLoader.java Für die Implementierungsquelle zeigt beide Pfade, die überprüft werden (OpenJDK)

In dem Fall, in dem das Problem darin besteht, dass das System die betreffende DLL nicht finden kann, ist ein gemeinsames Missverständnis (verstärkt durch die Fehlermeldung von Java), dass die Systemeigenschaft Java.library.Path die Antwort ist. Wenn Sie die Systemeigenschaft java.library.path auf das Verzeichnis festlegen, in dem sich Ihre DLL befindet, dann wird System.loadlibrary tatsächlich Ihre DLL finden. Wenn Ihre DLL jedoch wie häufig von anderen DLLs abhängt, kann Java.library nicht helfen, da die Belastung der abhängigen DLLs vollständig vom Betriebssystem verwaltet wird, das nichts über Java.library weiß. Weg. Daher ist es fast immer besser, Java.library.Path zu umgehen und einfach Ihr DLL -Verzeichnis zu ld_library_path (Linux), DYLD_LIBRARY_PATH (MACOS) oder Pfad (Windows) hinzuzufügen, bevor Sie die JVM starten.

(Hinweis: Ich verwende den Begriff "DLL" im allgemeinen Sinne von DLL oder Shared Library.)

Wenn Sie eine Datei laden müssen, die relativ zu einem Verzeichnis ist, in dem Sie sich bereits befinden (wie im aktuellen Verzeichnis), finden Sie hier eine einfache Lösung:

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());

Für diejenigen, die suchen java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path

Ich war mit der gleichen Ausnahme ausgesetzt; Ich habe alles und wichtige Dinge ausprobiert, damit es funktioniert, sind:

  1. Richtige Version von PDF lib.jar (in meinem Fall war es falsch, Version Jar in der Serverlaufzeit gehalten)
  2. Erstellen Sie einen Ordner und halten Sie das PDFLIB -Glas in der Lage, den Ordner in Ihre Pfadvariable hinzu

Es hat mit Tomcat 6 funktioniert.

Ich armer ! verbrachte einen ganzen Tag dahinter. Schreiben Sie es hier unten, wenn ein Körper dieses Problem wiederholt.

Ich versuchte zu laden, wie Adam vorschlug, wurde aber dann mit AMD64 gegen IA 32 -Ausnahme erwischt. Ihr JRE und Ihr JDK sind 64 Bit und Sie haben es Ihrem Klassenpfad korrekt hinzugefügt.

Mein funktionierendes Beispiel geht hier:Unzufriedener Verbindungsfehler

  1. Wenn Sie glauben, dass Sie einen Weg der nativen Lib zu %Path %hinzugefügt haben, testen Sie sich noch einmal nach:

    System.out.println (System.getProperty ("java.library.Path"))

Es sollte Ihnen tatsächlich zeigen, ob Ihre DLL auf %Path %ist

  1. Starten Sie die Ide -Idee neu, ja, es schien für mich zu funktionieren, nachdem ich eine Env -Variable eingerichtet habe, indem ich sie dem %path %hinzufügen habe

Für Windows habe ich festgestellt, dass beim Laden der Füllstände (jd2xsx.dll -Anrufe & ftd2xx.dll) in den Ordner windowWS/system32 die Probleme behoben haben. Ich hatte dann ein Problem mit meinem neueren FD2XX.dll mit Parametern, weshalb ich die ältere Version dieser DLL laden musste. Ich werde das später ausfeuern müssen.

Hinweis: Der jd2xsx.dll ruft die ftd2xx.dll auf, sodass der Pfad für die jd2xx.dll möglicherweise nicht funktioniert.

Ich verwende Mac OS X Yosemite und Netbeans 8.02, ich habe den gleichen Fehler und die einfache Lösung, die ich gefunden habe, ist wie oben. Dies ist nützlich, wenn Sie native Bibliothek in das Projekt aufnehmen müssen. Also das nächste für 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

Ich hoffe, es könnte für jemanden nützlich sein. Der Link, in dem ich die Lösung gefunden habe, ist hier:java.library.path - Was ist es und wie man benutzt

Ich hatte das gleiche Problem und der Fehler lag auf eine Umbenennung der DLL. Es könnte passieren, dass der Bibliotheksname auch irgendwo in der DLL geschrieben ist. Wenn ich seinen ursprünglichen Namen zurücklegte, konnte ich mit dem Laden geladen werden System.loadLibrary

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 Server\100\Tools\Binn\
     C:\Program Files\Microsoft SQL Server\100\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 Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\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;





    }


}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top