Подтвердить что ты не робот

Разница между использованием java.library.path и LD_LIBRARY_PATH

Есть ли разница между использованием параметра jvm

-Djava.library.path=/path 

при запуске jvm

и установка переменной пути Linux

export LD_LIBRARY_PATH=/path 

до запуска JVM. Существуют ли какие-либо преимущества/недостатки для двух вариантов?

4b9b3361

Ответ 1

Первая форма

-Djava.library.path=/path

будет обрабатываться на уровне байт-кода java, System.loadLibrary вызовет Runtime.loadLibary, затем вызовет java/lang/ClassLoader.loadLibrary. В вызове функции ClassLoader.loadLibrary будет проверено системное свойство java.library.path, чтобы получить полный путь к библиотеке и передать полный путь к собственному коду, чтобы вызвать систему api dlopen/dlsym, в конечном итоге сделать библиотеку загруженной. Вы можете просмотреть исходный код из OpenJDK репозитория. Следующий фрагмент кода является копией сегмента я из ссылки.

Преимущество этой формы заключается в том, что вы получите ошибку или предупреждение или исключение в Java-коде, если есть некоторые проблемы с вашим пути к библиотеке.

// 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);
    }
// ....

Вторая форма

export LD_LIBRARY_PATH=/path

будет обрабатываться в native, в соответствии с документом 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.)

Таким образом, если есть некоторые проблемы с вашим пути к библиотеке, и система не может загрузить вашу библиотеку, система не даст слишком много подсказки о том, что произойдет, и будет терпеть неудачу (я думаю). Это зависит от того, следует ли реализовать LD_LIBRARY_PATH, Android не использовал LD_LIBRARY_PATH для определения местоположения библиотеки, вы можете увидеть реализацию Android из здесь.

Ответ 2

Java может явно загружать библиотеки, перечисленные в -Djava.library.path=... как описано alijandro.

Например, если в режиме привязок используется серия mq, путь для необходимых библиотек может быть указан с помощью -Djava.library.path=/opt/mq/java/lib, а mqseries загружает библиотеки.

Если библиотека не эксцессуально загружена из java, то есть необходимо использовать зависимую библиотеку, тогда LD_LIBRARY_PATH следует использовать для доступа к этой библиотеке в jvm.