尽管dll位于正确的目录中,但链接错误仍不令人满意

时间:2018-11-29 10:34:37

标签: java dll java-native-interface

在这里很迷路。所以我有这个Spring应用程序,它一开始就以这种方式在主类中加载我的.dll(自定义文件):

static {
    File f = new File("src/lib/lib.dll");
    if(f.exists() && !f.isDirectory()) {
        String libDllPath = f.getParentFile().getAbsolutePath();
        log.info("libDllPath: {}", libDllPath);
        System.setProperty( "java.library.path", libDllPath);
        Field fieldSysPath = null;
        try {
            fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
            fieldSysPath.setAccessible( true );
            fieldSysPath.set( null, null );
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        log.info("\"java.library.path\" : {}", System.getProperty("java.library.path"));
        System.loadLibrary("lib");
    }
    else {
        log.error("Lib has not been loaded.");
        System.exit(-1);
    }
}

如果我从IntelliJ启动应用程序,并且实际上正在加载.dll,就像此处建议的那样https://stackoverflow.com/a/6909689/3045845

,那么这段代码可以正常工作

记录器的输出为:

11:14:39.287 [main] INFO  com.spring.application- libDllPath: D:\Workspace\whatever\spring-application\src\lib
11:14:39.289 [main] INFO  com.whatever - "java.library.path" : D:\Workspace\whatever\spring-application\src\lib

记录下来,这是项目目录树:

src
|----lib
      |----lib.dll
|----main
      |----java
             |----com.main.package
      |----resources
|----test

因此,我已使用Gradle从此应用程序构建了jar文件,并尝试在Windows Server 2012上部署该应用程序,因为这是该应用程序的目标操作系统。

在那儿,我正在使用java -jar spring-application-1.0-SNAPSHOT.jar将jar文件部署到某个默认文件夹中(我尝试在正在开发应用程序的Windows10下部署相同的jar –就像一个咒语一样),这就是我得到的: / p>

C:\Users\user\Downloads>java -jar spring-application-1.0-SNAPSHOT.jar
11:27:55.841 [main] INFO  com.spring.application - libDllPath: C:\Users\user\Downloads\src\lib
11:27:55.853 [main] INFO  com.spring.application - "java.library.path" : C:\Users\user\Downloads\src\lib
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\user\Downloads\src\lib\lib.dll: Can't find dependent libraries
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(Unknown Source)
        at java.lang.ClassLoader.loadLibrary(Unknown Source)
        at java.lang.Runtime.load0(Unknown Source)
        at java.lang.System.load(Unknown Source)
        at com.spring.application.<clinit>(SpringApplication.java:51)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)

我确保实际上确实在目录中包含.dll。

我还尝试将-Djava.library.path=设置为包含.dll的目录来运行jar,但同样的情况也会发生。

有人可以告诉我这是怎么回事吗?

1 个答案:

答案 0 :(得分:0)

因此,显然它无法正常工作的原因是dll本身同时依赖于MSCVP120D.dllMSCVR120D.dll。我使用Dependency Walker程序来跟踪在Windows Server 2012上这两个dll都不可用的情况。

要解决此问题,使用Visual Studio 2013编译器(C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat)进行的编译应与/MTd标志一起运行,如本文中所述:https://stackoverflow.com/a/32085978