Domanda

Come posso caricare un file dll personalizzato nella mia applicazione web? Ho provato a seguire i modi ma non ci riesce.

  • ha copiato tutte le DLL richieste nella cartella system32 e ha provato a caricarne una nella funzione di costruzione Servlet System.loadLibrary
  • DLL richieste copiate in tomcat_home / shared / lib e tomcat_home/common/lib
  • tutte queste DLL sono in WEB-INF / lib dell'applicazione web
È stato utile?

Soluzione

Affinché System.loadLibrary () funzioni, la libreria (su Windows, una DLL) deve trovarsi in una directory da qualche parte sul tuo PATH o su un percorso elencato nella proprietà di sistema java.library.path (in modo da poter avviare Java come java -Djava.library.path = / path / to / dir ).

Inoltre, per loadLibrary () , si specifica il nome di base della libreria, senza .dll alla fine. Quindi, per /path/to/something.dll , useresti semplicemente System.loadLibrary (" qualcosa ") .

Devi anche guardare l'esatto UnsatisfiedLinkError che stai ricevendo. Se dice qualcosa del tipo:

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

allora non riesce a trovare la libreria foo (foo.dll) nel tuo PATH o java.library.path . Se dice qualcosa del tipo:

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

allora qualcosa non va nella libreria stessa, nel senso che Java non è in grado di mappare una funzione Java nativa nella tua applicazione alla sua controparte nativa effettiva.

Per cominciare, vorrei mettere un po 'di log intorno alla tua chiamata System.loadLibrary () per vedere se questo funziona correttamente. Se genera un'eccezione o non si trova in un percorso del codice che viene effettivamente eseguito, otterrai sempre l'ultimo tipo di UnsatisfiedLinkError spiegato sopra.

Come sidenote, la maggior parte delle persone inserisce le proprie chiamate loadLibrary () in un blocco di inizializzatore statico nella classe con i metodi nativi, per assicurarsi che venga sempre eseguito esattamente una volta:

class Foo {

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

    public Foo() {
    }

}

Altri suggerimenti

La modifica della variabile 'java.library.path' in fase di runtime non è sufficiente perché viene letta una sola volta da JVM. Devi ripristinarlo come:

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

Per favore, prendi un bottino a: Modifica Percorso libreria Java in fase di esecuzione .

La risposta originale di Adam Batkin ti porterà a una soluzione, ma se ridistribuisci la tua webapp (senza riavviare il tuo contenitore web), dovresti riscontrare il seguente errore:

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)

Ciò accade perché ClassLoader che originariamente ha caricato la DLL fa ancora riferimento a questa DLL. Tuttavia, la tua webapp ora è in esecuzione con un nuovo ClassLoader e poiché la stessa JVM è in esecuzione e una JVM non consente 2 riferimenti alla stessa DLL, non puoi ricaricare . Pertanto, la tua webapp non può accedere alla DLL esistente e non può caricarne una nuova. Quindi .... sei bloccato.

documentazione ClassLoader di Tomcat delinea il motivo per cui la tua webapp ricaricata viene eseguita in un nuovo isolato ClassLoader e come aggirare questa limitazione (a un livello molto alto).

La soluzione è di estendere leggermente la soluzione di 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) {
        }

    }

Quindi posizionando un jar contenente JUST questa classe compilata nella cartella TOMCAT_HOME / lib.

Ora, all'interno della tua webapp, devi solo forzare Tomcat a fare riferimento a questa classe, che può essere fatta semplicemente come questa:

  Class.forName("awesome.Foo");

Ora la tua DLL dovrebbe essere caricata nel classloader comune e può essere referenziata dal tuo webapp anche dopo essere stata ridistribuita.

Ha senso?

Una copia di riferimento funzionante è disponibile sul codice google, static-dll-bootstrapper .

Puoi usare System.load () per fornire un percorso assoluto che è quello che vuoi, piuttosto che un file nella cartella della libreria standard per il rispettivo sistema operativo.

Se vuoi applicazioni native già esistenti, usa System.loadLibrary (nome file stringa) . Se vuoi fornire il tuo probabilmente stai meglio con load ().

Dovresti anche essere in grado di usare loadLibrary con java.library.path impostato correttamente. Vedi ClassLoader.java per l'origine dell'implementazione mostrando entrambi i percorsi da verificare (OpenJDK)

Nel caso in cui il problema sia che System.loadLibrary non riesce a trovare la DLL in questione, un malinteso comune (rafforzato dal messaggio di errore di Java) è che la proprietà di sistema java.library.path è la risposta. Se si imposta la proprietà di sistema java.library.path sulla directory in cui si trova la DLL, System.loadLibrary troverà effettivamente la DLL. Tuttavia, se la tua DLL a sua volta dipende da altre DLL, come spesso accade, java.library.path non può essere di aiuto, perché il caricamento delle DLL dipendenti è gestito interamente dal sistema operativo, che non conosce nulla di java.library. sentiero. Pertanto, è quasi sempre meglio ignorare java.library.path e semplicemente aggiungere la directory della DLL a LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS) o Path (Windows) prima di avviare JVM.

(Nota: sto usando il termine "DLL" nel senso generico di DLL o libreria condivisa.)

Se devi caricare un file relativo ad alcune directory in cui ti trovi già (come nella directory corrente), ecco una soluzione semplice:

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

Per chi cerca java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path

Stavo affrontando la stessa eccezione; Ho provato di tutto e le cose importanti per farlo funzionare sono:

  1. Versione corretta di pdf lib.jar (Nel mio caso era un vaso versione errato tenuto in fase di esecuzione del server)
  2. Crea una cartella e tieni dentro il barattolo pdflib e aggiungi la cartella nella tua variabile PATH

Ha funzionato con Tomcat 6.

Povero me! abbiamo trascorso un'intera giornata alle spalle. Scriverlo qui se un corpo replica questo problema.

Stavo cercando di caricare come suggerito Adam, ma poi mi sono sorpreso con l'eccezione AMD64 vs IA 32.Se in ogni caso dopo aver lavorato secondo la procedura dettagliata di Adam (senza dubbio la scelta migliore), prova ad avere una versione a 64 bit dell'ultima jre .Assicurati che JRE E JDK siano a 64 bit e che tu l'abbia aggiunto correttamente al tuo percorso di classe.

Il mio esempio di lavoro va qui: errore di collegamento non soddisfatto

  1. Se ritieni di aver aggiunto un percorso di lib nativo a% PATH%, mettiti alla prova ancora una volta:

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

Dovrebbe mostrarti effettivamente se la tua dll è su% PATH%

  1. Riavvia IDE Idea, sì, sembrava funzionare per me dopo aver impostato la variabile env con l'aggiunta a% PATH%

Per Windows ho scoperto che quando ho caricato i riempimenti (jd2xsx.dll chiama & amp; ftd2xx.dll) nella cartella windowws / system32 questo ha risolto i problemi. Ho quindi avuto un problema con il mio nuovo fd2xx.dll relativo ai parametri, motivo per cui ho dovuto caricare la versione precedente di questa dll. Dovrò risolverlo più tardi.

Nota: jd2xsx.dll chiama ftd2xx.dll, pertanto l'impostazione del percorso per jd2xx.dll potrebbe non funzionare.

Sto usando Mac OS X Yosemite e Netbeans 8.02, ho avuto lo stesso errore e la semplice soluzione che ho trovato è come sopra, questo è utile quando è necessario includere la libreria nativa nel progetto. Quindi fai il prossimo per 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

Spero possa essere utile per qualcuno. Il link in cui ho trovato la soluzione è qui: java.library. percorso & # 8211; Che cos'è e come si utilizza

Ho avuto lo stesso problema e l'errore era dovuto a una ridenominazione della dll. Potrebbe succedere che il nome della libreria sia scritto anche da qualche parte all'interno della dll. Quando ho riportato il suo nome originale sono stato in grado di caricare utilizzando 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;





    }


}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top