是-Djava.library.path = …相当于System.setProperty(“java.library.path”,…)

我加载了放在./lib的外部库。 这两个解决scheme设置java.library.path等效?

  1. 执行jar时在控制台中设置path:

     java -Djava.library.path=./lib -jar myApplication.jar 
  2. 加载库之前在代码中设置path:

     System.setProperty("java.library.path", "./lib"); 

如果它们是相同的 ,那么为什么在第二种解决scheme中Java可能找不到这个库,而第一个可以呢?

如果不是的话 ,有没有办法在代码中设置path?

一般来说,这两种方法的净效应是相同的,系统属性java.library.path被设置为值./lib

但是 ,某些系统属性仅在特定时间点进行评估,例如JVM的启动。 如果 java.library.path属于这些属性(而且您的实验似乎表明了这一点),那么使用第二种方法除了在将来调用getProperty()返回新值之外,将没有明显的效果。

根据经验,使用-D命令行属性适用于所有系统属性,而System.setProperty()仅适用于不仅在启动过程中进行检查的属性。

尽pipe没有很好的文档,但就System.loadLibrary()方法而言, java.library.path系统属性是“只读”属性。 这是一个报告的错误,但它被Sunclosures,而不是修复。 问题是JVM的ClassLoader在启动时读取一次该属性,然后将其caching,不允许我们在之后以编程方式更改它。 System.setProperty("java.library.path", anyVal); 除了System.getProperty()方法调用之外,将没有任何效果。

幸运的是,有人在Sun论坛上发布了一个解决方法 。 不幸的是,该链接不再有效,但我确实在另一个来源find了代码 。 这里是你可以用来解决无法设置java.library.path系统属性的代码:

 public static void addDir(String s) throws IOException { try { // This enables the java.library.path to be modified at runtime // From a Sun engineer at http://forums.sun.com/thread.jspa?threadID=707176 // Field field = ClassLoader.class.getDeclaredField("usr_paths"); field.setAccessible(true); String[] paths = (String[])field.get(null); for (int i = 0; i < paths.length; i++) { if (s.equals(paths[i])) { return; } } String[] tmp = new String[paths.length+1]; System.arraycopy(paths,0,tmp,0,paths.length); tmp[paths.length] = s; field.set(null,tmp); System.setProperty("java.library.path", System.getProperty("java.library.path") + File.pathSeparator + s); } catch (IllegalAccessException e) { throw new IOException("Failed to get permissions to set library path"); } catch (NoSuchFieldException e) { throw new IOException("Failed to get field handle to set library path"); } } 

警告:这可能不适用于所有平台和/或JVM。

你可以添加三行

  System.setProperty("java.library.path", "/path/to/libs" ); Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" ); fieldSysPath.setAccessible( true ); fieldSysPath.set( null, null ); 

还可以导入java.lang.reflect.Field解决这个问题是可以的