在Java项目中,我使用的是通过
加载一些本机库的第三方库System.loadLibrary("libName");
我希望能够在我的应用程序中影响此方法的搜索路径,以便用户无需在命令行上指定正确的java.library.path值(此值取决于当前的操作系统和架构)。例如,我希望将它设置为“lib / native / windows”,在Linux 32bit上设置为“lib / native / linux32”等。
我试过
System.setProperty("java.library.path", ...)
但是这被忽略了,显然是因为JVM在我的代码运行之前只读取了一次该属性。
我还尝试在使用依赖于
的Java库之前加载本机库System.load("fullPath/lib")
此调用成功,但当使用System.loadLibrary()再次加载本机库时,仍会出现UnsatisfiedLinkError。
我找到的唯一方法如下:
这很有效,但我发现它非常复杂并且需要付出很多努力,因为我需要添加所有这些接口。有更简单的方法吗?
答案 0 :(得分:5)
我需要更改单元测试的dll路径。我尝试了以下hack并且它有效:
System.setProperty( "java.library.path", "/path/to/libs" );
Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
fieldSysPath.setAccessible( true );
fieldSysPath.set( null, null );
有关说明,请参阅original link。
答案 1 :(得分:2)
最近才遇到此问题,并使用OpenJDK抛出NullPointerException(因为0-0提到了Samil的答案)。以下OpenJDK中的作品,应该与Oracle JDK一起使用。
System.setProperty("java.library.path", newPath);
Field field = ClassLoader.class.getDeclaredField("sys_paths");
field.setAccessible(true);
field.set(ClassLoader.getSystemClassLoader(), new String[]{newPath});
String libPath = System.getProperty("java.library.path");
String newPath;
if (libPath == null || libPath.isEmpty()) {
newPath = path;
} else {
newPath = path + File.pathSeparator + libPath;
}
System.setProperty("java.library.path", newPath);
Field field = ClassLoader.class.getDeclaredField("sys_paths");
field.setAccessible(true);
// Create override for sys_paths
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
List<String> newSysPaths = new ArrayList<>();
newSysPaths.add(path);
newSysPaths.addAll(Arrays.asList((String[])field.get(classLoader)));
field.set(classLoader, newSysPaths.toArray(new String[newSysPaths.size()]));
答案 2 :(得分:1)
根据您上面的评论(特别是第三方库的行为),我想说您最好的选择是在启动JVM时使库路径正确。
答案 3 :(得分:1)
我尝试跟随在我的Mac上为Java应用程序加载本机Growl库,其中lib位于我的应用程序的类路径的根目录中:
System.load(GrowlUtils.class.getResource("/libgrowl.jnilib").getFile().toString());
答案 4 :(得分:0)
有更简单的方法吗?
是,提供批处理/脚本文件以启动应用程序。然后,您可以在批处理/ shell文件中设置正确的路径,甚至可以从环境变量中读取值。比在应用程序内部尝试更容易。
答案 5 :(得分:0)
尽管从技术上讲这些答案正确无误。在Windows上设置环境变量PATH或在unix上设置环境变量LD_LIBRARY_PATH将会更改jvm查找库的位置: What is LD_LIBRARY_PATH and how to use it?
在Linux上: 导出LD_LIBRARY_PATH = / usr /.../ 然后: Java ....