【发布时间】:2015-05-04 15:21:32
【问题描述】:
我目前正在维护一个 Java 通信库,它通过 JNI 包装了一些 dll 提供的功能。在某些时候,在 Java 中,我需要加载 JNI 包装器来转发我的请求并最终调用本机库。目前,这是通过调用来完成的
System.loadLibrary("MyLibrary");
如here 所述,如果它位于java.library.path 内的某个位置,则应该始终找到MyLibrary。目前,我的java.library.path 似乎包含一些 Java 特定文件夹以及 %PATH% 环境变量中指定的所有目录:
C:\Program Files\Java\jdk1.8.0_45\bin;
C:\Windows\Sun\Java\bin;
C:\Windows\system32;
C:\Windows;
C:\Program Files\ImageMagick-6.9.0-Q16;
C:\ProgramData\Oracle\Java\javapath;
C:\Windows\system32;
C:\Windows;
C:\Windows\System32\Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0\;
C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;
C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;
C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;
C:\texlive\2014\bin\win32;
C:\MyFolder\Common32;
C:\MyFolder\Common64;
C:\Program Files (x86)\Microsoft Team Foundation Server 2012 Power Tools\;
C:\Program Files (x86)\Microsoft Team Foundation Server 2012 Power Tools\Best Practices Analyzer\;.
我现在的问题是,即使将MyLibrary 放在C:\MyFolder\Common64; 中,上面的loadLibrary 调用也会产生UnsatisfiedLinkError,我似乎无法理解为什么。但是,当我将它放入 System32 文件夹时,或者如果我在绝对指定路径时调用 load 时会发现它:
System.load("C:\\MyFolder\\Common64\\MyLibrary.dll");
我尝试使用here 和here 给出的答案中建议的sys_path 技巧在运行时弄乱java.library.path。以下工作完美无缺:
System.setProperty("java.library.path", "C:\\MyFolder\\Common64\\" );
Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
fieldSysPath.setAccessible( true );
fieldSysPath.set( null, null );
System.loadLibrary("MyLibrary");
因此,如果我将整个 java.library.path 属性替换为自定义路径,则 dll 将成功加载。但是,这不是所需的行为,因为我想通过将正确的目录添加到 %PATH% 来动态查找 dll。此外,像这样将我的自定义路径添加到java.library.path
String curJavaLibraryPath = System.getProperty("java.library.path");
System.setProperty("java.library.path", curJavaLibraryPath + ";C:\\MyFolder\\Common64\\" );
也不行。
目前我正在尝试在 Win7 64 位机器上进行这项工作。如果相关的话,我的 dll 也被编译为 x64。
当我在 x86 模式下编译我的 Java 库并将相应的 JNI dll 复制到 C:\MyFolder\Common32\ 并将该目录添加到 %PATH% 时,一般过程可以完美运行。
【问题讨论】:
-
jdk 或 jre 是否在 64 位运行应用程序?你试过把dll放在
C:\Windows\SysWOW64目录下吗? -
当我将 dll 放在
System32文件夹中时,加载 dll 已经可以工作了(在 x64 系统上,这是放置 x64 库的地方)。但是,我希望通过让用户将其放在任何他/她想要的位置,然后将具有相应文件夹的条目添加到PATH来动态找到 dll -
是的,我知道
-D标志以及通过IDE 设置java.library.path。但这对我没有帮助,因为我只想依赖 %PATH% 变量。我只是想不通,为什么即使它已经在正确的路径中,它也不会加载 dll。 -
您到底想做什么?将文件放在 %PATH% 中还是从自定义目录加载?如果要将其放在“默认”Windows %PATH% 上,则必须将 dll 放入通过在命令提示符处调用
echo %PATH%列出的文件夹之一。如果要从自定义目录加载它,则必须使用 System.load("Path to dll") 加载它,而 not 使用 System.loadLibrary() 加载它。或者你必须修改你的 %PATH% 变量,但这有时需要重启你的机器。
标签: java java-native-interface 64-bit environment-variables