Diferença entre o uso de java.library.path e LD_LIBRARY_PATH

Existe uma diferença entre definir o argumento da JVM

-Djava.library.path=/path 

na boot da JVM e definindo a variável de ambiente do Linux

 export LD_LIBRARY_PATH=/path 

antes de a JVM ser iniciada?

Quais são as vantagens / desvantagens das duas abordagens?

A primeira forma

 -Djava.library.path=/path 

será manipulado no nível do bytecode java, o System.loadLibrary chamará Runtime.loadLibary , em seguida, chamará java/lang/ClassLoader.loadLibrary . Na chamada de function ClassLoader.loadLibrary , a propriedade do sistema java.library.path será verificada para obter o caminho completo da biblioteca e passar esse caminho completo para o código nativo para chamar o api dlopen/dlsym sistema dlopen/dlsym , eventualmente, tornar a biblioteca carregada. Você pode procurar a fonte do repository OpenJDK . O trecho de código a seguir é o segmento que copio do link.

A vantagem dessa forma é que você obterá erro ou aviso ou exceção no código Java, se houver algum problema com o caminho da sua biblioteca.

 // Invoked in the java.lang.Runtime class to implement load and loadLibrary. static void loadLibrary(Class fromClass, String name, boolean isAbsolute) { ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); if (sys_paths == null) { usr_paths = initializePath("java.library.path"); sys_paths = initializePath("sun.boot.library.path"); } if (isAbsolute) { if (loadLibrary0(fromClass, new File(name))) { return; } throw new UnsatisfiedLinkError("Can't load library: " + name); } // .... 

A segunda forma

 export LD_LIBRARY_PATH=/path 

será tratado em nativo, de acordo com o documento do dlopen/dlsym

  dlopen() The function dlopen() loads the dynamic library file named by the null-terminated string filename and returns an opaque "handle" for the dynamic library. If filename is NULL, then the returned handle is for the main program. If filename contains a slash ("/"), then it is interpreted as a (relative or absolute) pathname. Otherwise, the dynamic linker searches for the library as follows (see ld.so(8) for fur‐ ther details): o (ELF only) If the executable file for the calling program contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag, then the directories listed in the DT_RPATH tag are searched. o If, at the time that the program was started, the environment variable LD_LIBRARY_PATH was defined to contain a colon-separated list of directories, then these are searched. (As a security measure this variable is ignored for set-user-ID and set-group-ID programs.) 

Dessa maneira, se houver algum problema com o caminho da sua biblioteca e o sistema não puder carregar sua biblioteca, o sistema não dará muita pista do que acontecerá e falhará silenciosamente (eu acho). Depende se deve ou não implementar LD_LIBRARY_PATH , o Android não usou LD_LIBRARY_PATH para determinar a localização da biblioteca, você pode ver a implementação do Android a partir daqui .

Java pode carregar explicitamente as bibliotecas listadas com -Djava.library.path=... como descrito por alijandro.

Por exemplo, se mq series for usado no modo de ligações, o caminho para as bibliotecas necessárias pode ser especificado com -Djava.library.path=/opt/mq/java/lib e o mqseries carrega as bibliotecas.

Se uma biblioteca não for explicitamente carregada de java, ou seja, uma biblioteca dependente precisa ser usada, então LD_LIBRARY_PATH deve ser usado para ter essa biblioteca disponível no jvm.

Intereting Posts