2011-03-24 18 views
40

Cargué una biblioteca externa que se coloca en ./lib. ¿Son estas dos soluciones para establecer el equivalente de java.library.path?Is -Djava.library.path = ... equivalente a System.setProperty ("java.library.path", ...)

  1. camino situado en la consola cuando se ejecuta el tarro:

    java -Djava.library.path=./lib -jar myApplication.jar 
    
  2. ruta establecida en el código antes de la carga de bibliotecas:

    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?

+0

'java.library.path' se refiere al directorio * * no es una * archivo * – jacktrades

Respuesta

44

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

Sin embargo,, algunas propiedades del sistema solo se evalúan en momentos específicos, como el inicio de la JVM. Sijava.library.path es una de esas propiedades (y su experimento parece indicarlo), utilizar el segundo método no tendrá ningún efecto notable excepto para devolver el nuevo valor en las invocaciones futuras de getProperty().

Como regla general, usar 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.

43

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(). Esto es reported bug 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 posted a workaround on the Sun forums. Desafortunadamente, ese enlace ya no funciona pero encontré the code on another source. Este es el código que puede utilizar para evitar no poder establecer la propiedad java.library.path sistema:

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: Esto puede no funcionar en todas las plataformas y/o JVM.

+3

Consulte [esta respuesta más reciente] (http://stackoverflow.com/a/24988095/346561) por @luyifan que parece lograr lo mismo que esta respuesta, con menos código. –

32

puede 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 importar java.lang.reflect.Field Está bien para resolver el problema

+2

esto funciona bien (y es más simple que construir la ruta de la temperatura nosotros mismos como lo describe la solución de Jesse Webb) –

+0

Este es un salvavidas. Parece descuidado por Sun/Oracle para no proporcionar una forma más directa de cargar bibliotecas desde un directorio específico, definido por el tiempo de ejecución. – gromit190

Cuestiones relacionadas