Можно создать один файл JAR со всеми зависимостями, включая собственные библиотеки JNI для одной или нескольких платформ. Базовый механизм заключается в использовании System.load (File) для загрузки библиотеки вместо типичного System.loadLibrary (String), который ищет системное свойство java.library.path. Этот метод значительно упрощает установку, поскольку пользователю не нужно устанавливать библиотеку JNI в своей системе за счет, однако, того, что все платформы могут не поддерживаться, поскольку конкретная библиотека для платформы может не быть включена в один файл JAR. .
Процесс выглядит следующим образом:
- включить собственные библиотеки JNI в файл JAR в месте, специфическом для платформы, например, в NATIVE / $ {os.arch} / $ {os.name} /libname.lib
- создать код в статическом инициализаторе основного класса, чтобы
- вычислить текущие os.arch и os.name
- найдите библиотеку в файле JAR в предопределенном месте с помощью Class.getResource (String)
- если он существует, извлеките его во временный файл и загрузите с помощью System.load (File).
Я добавил функциональность, чтобы сделать это для jzmq, привязок Java к ZeroMQ (бесстыдный плагин). Код можно найти здесь . В коде jzmq используется гибридное решение, поэтому, если встроенная библиотека не может быть загружена, код вернется к поиску библиотеки JNI по пути java.library.path.
UnsatisfiedLinkError
что первая dll неявно хочет загрузить последнюю, но не может найти ее, так как она скрыта в банке. Также загрузка последней DLL первой не помогает.DLL
должны быть известны заранее, и их расположение должно быть добавлено вPATH
переменную среды.https://www.adamheinrich.com/blog/2012/12/how-to-load-native-jni-library-from-jar/
отличная статья, которая решает мою проблему ..
В моем случае у меня есть следующий код для инициализации библиотеки:
источник
Взгляните на One-JAR . Он заключит ваше приложение в один файл jar со специализированным загрузчиком классов, который, помимо прочего, обрабатывает "банки внутри jar".
Он обрабатывает собственные (JNI) библиотеки, при необходимости распаковывая их во временную рабочую папку.
(Отказ от ответственности: я никогда не использовал One-JAR, пока в нем не нуждался, просто пометил его закладкой на черный день.)
источник
1) Включите родную библиотеку в свой JAR как ресурс. E. g. с Maven или Gradle и стандартным макетом проекта поместите собственную библиотеку в
main/resources
каталог.2) Где-то в статических инициализаторах Java-классов, относящихся к этой библиотеке, поместите такой код:
источник
JarClassLoader - это загрузчик классов для загрузки классов, собственных библиотек и ресурсов из одного монстра JAR и из JAR внутри монстра JAR.
источник
Возможно, вам придется отключить родную библиотеку от локальной файловой системы. Насколько мне известно, часть кода, выполняющая встроенную загрузку, смотрит на файловую систему.
Этот код должен помочь вам начать работу (я давно не смотрел на него, и он предназначен для другой цели, но должен помочь, и я очень занят в данный момент, но если у вас есть вопросы, просто оставьте комментарий и я отвечу, как только смогу).
источник
Решение для Котлина:
build.gradle.dsl
: скопируйте среду выполнения kotlin (kotlin-stdlib-1.4.0.jar) и собственную библиотеку (librust_kotlin.dylib) в JARmain
метод: скопируйте библиотеку во временный файл, чтобы загрузить ее по абсолютному путиисточник