Java.lang.UnsatisfiedLinkError no******.dll en java.biblioteca.camino


¿Cómo puedo cargar un archivo dll personalizado en mi aplicación web? Intenté seguir caminos, pero está fallando.

  • copió todos los archivos DLL necesarios en la carpeta system32 y trató de cargar uno de ellos en Servlet constructor System.loadLibrary
  • Copiado dlls requeridos en tomcat_home/shared/lib y tomcat_home/common/lib
  • todas estas dll están en WEB-INF/lib de la aplicación web
Author: Adam Batkin, 2009-09-10

12 answers

Para que System.loadLibrary() funcione, la biblioteca (en Windows, una DLL) debe estar en un directorio en algún lugar de su PATH o en una ruta listada en la propiedad del sistema java.library.path (por lo que puede lanzar Java como java -Djava.library.path=/path/to/dir).

Además, para loadLibrary(), se especifica el nombre base de la biblioteca, sin el .dll al final. Entonces, para /path/to/something.dll, solo usarías System.loadLibrary("something").

También necesitas mirar el UnsatisfiedLinkError exacto que estás obteniendo. Si dice algo como:

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

, Entonces no se puede encontrar la biblioteca foo (foo.dll) en su PATH o java.library.path. Si dice algo como:

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

Entonces algo está mal con la biblioteca en sí en el sentido de que Java no es capaz de mapear una función Java nativa en su aplicación a su contraparte nativa real.

Para empezar, pondría un poco de registro alrededor de su llamada System.loadLibrary() para ver si se ejecuta correctamente. Si lanza una excepción o no está en una ruta de código que realmente se ejecuta, entonces siempre obtenga el último tipo de UnsatisfiedLinkError explicado anteriormente.

Como nota lateral, la mayoría de las personas ponen sus llamadas loadLibrary() en un bloque inicializador estático en la clase con los métodos nativos, para asegurarse de que siempre se ejecuta exactamente una vez:

class Foo {

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

    public Foo() {
    }

}
 135
Author: Adam Batkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-10 07:33:09

La respuesta original de Adam Batkin le llevará a una solución, pero si vuelve a implementar su aplicación web (sin reiniciar su contenedor web), debería encontrarse con el siguiente error:

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)

Esto sucede porque el ClassLoader que originalmente cargó su DLL todavía hace referencia a esta DLL. Sin embargo, su aplicación web ahora se está ejecutando con un nuevo ClassLoader, y debido a que la misma JVM se está ejecutando y una JVM no permitirá 2 referencias a la misma DLL, no puede recargarla. Así, tu webapp no se puede acceder a la DLL existente y no se puede cargar una nueva. Tan.... estás atascado.

La documentación de ClassLoader de Tomcat describe por qué su aplicación web reloaded se ejecuta en un nuevo ClassLoader aislado y cómo puede evitar esta limitación (a un nivel muy alto).

La solución es extender un poco la solución de 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) {
        }

    }

Luego coloca un jar que contiene SOLO esta clase compilada en la carpeta TOMCAT_HOME/lib.

Ahora, dentro de su aplicación web, simplemente tiene que forzar a Tomcat a hacer referencia a esta clase, lo que se puede hacer tan simplemente como esto:

  Class.forName("awesome.Foo");

Ahora su DLL debe cargarse en el classloader común, y puede ser referenciado desde su aplicación web incluso después de ser redistribuido.

¿Tiene sentido?

Se puede encontrar una copia de referencia de trabajo en google code, static-dll-bootstrapper .

 10
Author: Matt M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-06 14:45:54

Cambiando 'java.biblioteca.la variable path en tiempo de ejecución no es suficiente porque JVM solo la lee una vez. Tienes que restablecerlo como:

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

Por favor, tome un botín en: Cambiando la ruta de la Biblioteca Java en tiempo de ejecución.

 10
Author: Alexandre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-12 14:01:56

Puede usar System.load() para proporcionar una ruta absoluta que es lo que desea, en lugar de un archivo en la carpeta de biblioteca estándar para el sistema operativo respectivo.

Si desea aplicaciones nativas que ya existen, use System.loadLibrary(String filename). Si quieres proporcionar el tuyo probablemente seas mejor con load ().

También debería ser capaz de usar loadLibrary con el java.library.path configurado correctamente. Véase ClassLoader.java para el origen de implementación que muestra ambas rutas que se están comprobando (OpenJDK)

 6
Author: Philip Whitehouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-19 21:41:00

En el caso donde el problema es ese Sistema.LoadLibrary no puede encontrar la DLL en cuestión, un error común (reforzado por el mensaje de error de Java) es que la propiedad del sistema java.biblioteca.el camino es la respuesta. Si establece la propiedad del sistema java.biblioteca.ruta al directorio donde se encuentra su DLL, luego Sistema.LoadLibrary de hecho encontrará su DLL. Sin embargo, si su DLL a su vez depende de otras DLL, como suele ser el caso, entonces java.biblioteca.camino no puede ayudar, porque la carga de las DLL dependientes son administradas enteramente por el sistema operativo, que no sabe nada de Java.biblioteca.camino. Por lo tanto, casi siempre es mejor omitir java.biblioteca.ruta y simplemente agregue el directorio de su DLL a LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (macOS) o Ruta (Windows) antes de iniciar la JVM.

(Nota: Estoy usando el término "DLL" en el sentido genérico de DLL o biblioteca compartida.)

 4
Author: Ian Emmons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-17 15:33:33

Para aquellos que buscan java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path

Me enfrentaba a la misma excepción; lo intenté todo y las cosas importantes para que funcionara son:

  1. Versión correcta de pdf lib.jar (En mi caso, era una versión incorrecta jar guardada en tiempo de ejecución del servidor)
  2. Haga una carpeta y mantenga el jar de pdflib en ella y agregue la carpeta en su variable PATH

Funcionó con tomcat 6.

 2
Author: Mangesh M. Kulkarni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-28 07:48:06

¡Pobre de mí ! pasé un día entero detrás de esto.Escribirlo aquí abajo si algún cuerpo replica este problema.

Estaba tratando de cargar como Adam sugirió, pero luego me atraparon con la excepción AMD64 vs IA 32.Si en cualquier caso después de trabajar según el tutorial de Adam (sin duda la mejor selección), intente tener una versión de 64 bits de la última versión de jre.Asegúrese de que su JRE Y JDK sean de 64 bits y que lo haya agregado correctamente a su classpath.

Mi ejemplo de trabajo va aquí: error de enlace no satisfecho

 2
Author: sayannayas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-19 21:07:35

Si necesita cargar un archivo que es relativo a algún directorio donde ya se encuentra (como en el directorio actual), aquí hay una solución fácil:

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
Author: Rick C. Hodgin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-13 17:40:13

Para Windows encontré que cuando cargué el filles(jd2xsx.llamadas dll & ftd2xx.dll) en la carpeta windowws/system32 esto resolvió los problemas. Entonces tuve un problema con mi más reciente fd2xx.dll tener que ver con parámetros que es por lo que tuve que cargar la versión anterior de este dll. Tendré que resolver esto más tarde.

Nota: el jd2xsx.dll llama a la ftd2xx.dll así que simplemente estableciendo el camino para el jd2xx.dll puede que no funcione.

 0
Author: Dan Carte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-06 20:37:03

Estoy usando Mac OS X Yosemite y Netbeans 8.02, obtuve el mismo error y la solución simple que he encontrado es como la anterior, esto es útil cuando necesita incluir una biblioteca nativa en el proyecto. Lo mismo ocurre con los 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

Espero que pueda ser útil para alguien. El enlace donde encontré la solución está aquí: java.biblioteca.path-Qué es y cómo usarlo

 0
Author: Alex Ventura,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-31 02:47:44

Tuve el mismo problema y el error se debió a un cambio de nombre de la dll. Podría suceder que el nombre de la biblioteca también esté escrito en algún lugar dentro de la dll. Cuando volví a poner su nombre original pude cargar usando System.loadLibrary

 0
Author: Alessandro Marini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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 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;





    }


}
 -1
Author: user3364275,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-30 04:16:47