我目前正在维护一个Java通信库,它封装了一些dll通过JNI提供的功能。在某种程度上,在Java中,我需要加载JNI包装器来转发我的请求,并最终调用本机库。目前,这是通过调用
System.loadLibrary("MyLibrary");正如所述的这里,如果MyLibrary放在java.library.path中的某个地方,则应该始终找到它。目前,我的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");我试图在运行时使用给出的java.library.path和这里的答案中所建议的sys_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复制到C:\MyFolder\Common32\并将该目录添加到%PATH%时,一般过程工作得非常完美。
发布于 2015-05-28 10:17:42
显然,loadLibrary()文档已经成功地欺骗了我。在UnsatisfiedLinkError的情况下,它声明
UnsatisfiedLinkError -如果库不存在。
因此,我显然认为loadLibrary()在任何时候都不能看到我指定的库。然而,情况并非如此,因为此异常也可能意味着它发现了错误(与VM不兼容)位数中的对应库。
据我所知,您唯一能做的检查就是分析异常所包含的错误消息,以确定您到底拥有哪个UnsatisfiedLinkError。我最后所做的就是:
try
{
System.setProperty(JAVA_LIBPATH_PROPNAME, libpath);
ForceReloadLibraryPath();
System.loadLibrary("AdsToJava");
}
catch (UnsatisfiedLinkError ex)
{
// We simply did not find the dll
if (ex.getMessage().equals("no MyLibrary in java.library.path")) {
// Just alert that nothing was found
} else if ( (ex.getMessage().endsWith("Can't load IA 32-bit .dll on a AMD 64-bit platform")) ||
(ex.getMessage().endsWith("Can't load AMD 64-bit .dll on a IA 32-bit platform")) ) {
// Extract the path at which the dll whith the wrong bitness was found
// and remove it from the search path and try again
}
}显然,在调用loadLibrary之前,您也可以预先检查搜索路径,但由于这种方法也适用于用户复制dll的情况,所以我认为这是最强大的选项。
https://stackoverflow.com/questions/30033785
复制相似问题