Если вы знаете путь к библиотеке, вы можете добавить путь к переменной среды java.library.path
в своем загрузчике пользовательских классов. Более простой подход - вычислить путь и использовать его при вызове Runtime.loadLibrary
.
Приведенный ниже код описывает два подхода: использование loadLibrary и установка системного свойства java.library.path.
if(CLASS_NAME.equals(name)) {
// two ways of doing this - either load the library explicitly from the full path
if (useFullPath) {
Runtime.getRuntime().loadLibrary("/full/path/to/mylibrary");
}
else { // or tweaking the library path
System.setProperty("java.library.path",
System.getProperty("java.library.path")
+ System.getProperty("file.separator")
+ "/path/to/lib");
}
}
return super.loadClass(name);
Вы упоминаете, что ваш код вызывается из jar - использование пользовательского загрузчика классов будет затруднено, если ClassLoader также является частью jar. Вы убедились, что ваш загрузчик классов действительно используется?
Более простой подход - изменить текущий вызов loadLibrary в вашем родном классе, чтобы использовать полный путь. Например. получить из системных свойств или вычислить его, если вы заранее знаете, где его найти. Конечно, это только вариант, если у вас есть исходный код для нативного класса. Если вы не можете изменить собственный класс, используйте вызов loadLibrary в загрузчике классов.
Насколько я понимаю, вызовы для загрузки библиотеки с одинаковым именем библиотеки (независимо от пути) загружают одну и ту же библиотеку. (По крайней мере, это поведение в Windows - я не проверял в Linux.) Таким образом, хотя загрузчик классов загружает библиотеку, используя полный путь, а собственный класс загружает библиотеку, используя ее простое имя, оба должны быть преобразованы в та же библиотека.
(Просто для полноты, разрешение эквивалентных библиотек происходит в ядре, опять же, исходя из опыта Win32. Каждая библиотека внутренне имеет имя, и Windows загружает только один экземпляр библиотеки с тем же внутренним именем на процесс.)