Is -Djava.library.path = … equivalente a System.setProperty (“java.library.path”, …)

./lib una biblioteca externa que se coloca en ./lib . ¿Son estas dos soluciones para establecer el equivalente de java.library.path?

  1. Establezca la ruta en la consola al ejecutar el jar:

     java -Djava.library.path=./lib -jar myApplication.jar 
  2. Establezca la ruta en el código antes de cargar la biblioteca:

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

Si son equivalentes , ¿por qué en la segunda solución puede Java no encontrar la biblioteca mientras la primera está bien?

Si no , ¿hay alguna manera de establecer el camino en el código?

En términos generales, ambos enfoques tienen el mismo efecto neto porque la propiedad del sistema java.library.path se establece en el valor ./lib .

Sin embargo , algunas propiedades del sistema solo se evalúan en puntos específicos en el tiempo, como el inicio de la JVM. Si java.library.path encuentra entre esas propiedades (y su experimento parece indicarlo), usar el segundo enfoque no tendrá ningún efecto notable excepto para devolver el nuevo valor en invocaciones futuras de getProperty() .

Como regla general, el uso de la propiedad de línea de comando -D funciona en todas las propiedades del sistema, mientras que System.setProperty() solo funciona en propiedades que no solo se verifican durante el inicio.

Aunque no está bien documentado, la propiedad del sistema java.library.path es una propiedad de “solo lectura” en lo que respecta al método System.loadLibrary() . Se trata de un error reportado pero Sun lo cerró en lugar de solucionarlo. El problema es que el ClassLoader de la JVM lee esta propiedad una vez en el inicio y luego la almacena en la memoria caché, lo que no nos permite cambiarla programáticamente después. La línea System.setProperty("java.library.path", anyVal); no tendrá ningún efecto excepto para las llamadas al método System.getProperty() .

Afortunadamente, alguien publicó una solución alternativa en los foros de Sun. Desafortunadamente, ese enlace ya no funciona pero encontré el código en otra fuente . Aquí está el código que puede usar para evitar la configuración de la propiedad del sistema 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"); } } 

ADVERTENCIA: Es posible que esto no funcione en todas las plataformas y / o JVM.

puedes agregar tres líneas

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

y también importa java.lang.reflect.Field Está bien resolver el problema