在 Java 项目中,我正在使用第三方库,它通过以下方式加载一些 native 库
System.loadLibrary("libName");
我希望能够从我的应用程序中影响此方法的搜索路径,以便用户不需要在命令行上指定正确的 java.library.path 值(此值取决于当前的操作系统和架构)。例如,在 Windows 上我想将它设置为“lib/native/windows”,在 Linux 32 位上设置为“lib/native/linux32”等。
我试过了
System.setProperty("java.library.path", ...)
但这被忽略了,显然是因为 JVM 在我的代码运行之前只读取了一次这个属性。
在使用依赖于它的Java库之前,我还尝试加载 native 库
System.load("fullPath/lib")
本次调用成功,但再次使用System.loadLibrary()加载 native 库时仍会出现UnsatisfiedLinkError。
我找到的唯一方法如下:
- 添加抽象外部库的整个 API 的接口(interface)。
- 在其余代码中仅使用这些接口(interface)。
- 添加实现接口(interface)并委托(delegate)给库的类。
- 写一个自己的ClassLoader,即
- 覆盖 findLibary() 以便在正确的路径中找到 native 库
- 覆盖 loadClass() 并自行加载外部库和包装层的所有类,而不是像默认的 ClassLoader 那样尝试委托(delegate)给其父级
- 确保接口(interface)使用正常的 ClassLoader 加载,包装类和外部库使用我自己的 ClassLoader 加载。
这行得通,但我发现它非常复杂并且需要付出很多努力,因为我需要添加所有这些接口(interface)。有没有更简单的方法?
最佳答案
我需要更改单元测试的 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 .
关于java - 如何通过 Java 代码影响 System.loadLibrary() 的搜索路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5013547/