Предотвращение загрузки библиотеки Java более одного раза

У меня есть несколько классов, которые используют одну и ту же библиотеку JNI, называемую "jni". В каждом из этих классов у меня есть вызов System.loadLibrary() в статическом инициализаторе класса:

Class class1 {
    static{
        System.loadLibrary("jni");
    }
    ...
}

Class class2 {
    static{
        System.loadLibrary("jni");
    }
    ...
}

Единственная проблема: я хочу, чтобы System.loadLibrary() вызывался один раз, так как это может занять некоторое время. Есть ли простой и чистый способ предотвратить множественные загрузки одной и той же библиотеки?

Ответы

Ответ 1

Если библиотека уже загружена, последующие вызовы для загрузки той же библиотеки будут проигнорированы.

System.loadLibrary:

Загружает системную библиотеку, указанную в аргумент libname. Способ в которое имя библиотеки отображается на актуальной системной библиотекой является система зависимыми.

Вызов System.loadLibrary(name) - это фактически эквивалентный вызову

 Runtime.getRuntime().loadLibrary(name)

Runtime.loadLibrary:

Загружает динамическую библиотеку с помощью указанное имя библиотеки. Файл содержащий нативный код загружается из локальная файловая система с места где обычно хранятся файлы библиотек получен. Детали этого процесса зависят от реализации. отображение из имени библиотеки в конкретное имя файла выполняется в системным образом.

Во-первых, если есть менеджер безопасности, его метод checkLink вызывается с libname в качестве аргумента. Это может приведет к исключению безопасности.

Метод System.loadLibrary(String) является обычным и удобным средство вызова этого метода. Если Нативные методы должны использоваться в реализация класса, стандартного стратегия состоит в том, чтобы поместить собственный код в файл библиотеки (назовите его LibFile) и затем поставить статический инициализатор:

 static { System.loadLibrary("LibFile"); }

в объявлении класса. Когда класс загружается и инициализируется, необходимая реализация собственного кода для собственных методов будет тогда также загружен.

Если этот метод вызывается больше, чем один раз с тем же именем библиотеки, вторых и последующих звонков игнорируются.

Ответ 2

Из JavaDocs -

Если этот метод вызывается более одного раза с тем же именем библиотеки, второй и последующие вызовы игнорируются.

Ответ 3

Я уверен, что любые последующие вызовы для загрузки уже загруженной библиотеки не имеют эффекта [править].

Это было проверено в исходном коде класса ClassLoader, но я все еще пытаюсь найти хороший источник для этого.

Ответ 4

Создайте одноэлементный класс, который загружает "jni" только во время его первого экземпляра и вызывает этот singleton в классах1 и class2 вместо System.loadLibrary( "jni" )