пути поиска, где одна нативная библиотека зависит от другой - PullRequest
0 голосов
/ 24 марта 2010

Я использую JNA и Java, но я думаю, что этот вопрос влияет на любой нативный нативный мост.

У меня есть Java-приложение, которое использует lib1.dylib, а lib1.dylib - lib2.dylib.

Я хочу поместить все в мой файл .app на Mac. Я могу легко поместить lib1.dylib внутрь и установить java.classpath (или NativeLibrary.addSearchPath ()), чтобы сообщить JVM, где найти lib1.dylib. Проблема в том, что я не знаю, как сообщить, что зависимости lib1.dylib также находятся в указанном мною месте. В результате lib1 загружается нормально, но затем lib2 не может быть найден, поскольку он не находится в пути к библиотеке операционной системы.

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

Ответы [ 2 ]

2 голосов
/ 25 марта 2010

Я сталкивался с этой проблемой раньше и только сегодня столкнулся с ней. Вы можете обойти это, добавив аргумент виртуальной машины «-Djava.library.path = / path / to / other / libs», но я помню, что Java использует это только для поиска начальной библиотеки, а затем использует системный PATH для поиска любых зависимостей.

Несколько решений, которые я пробовал раньше:

1) Используйте System.load (absolutePath) в зависимой библиотеке перед загрузкой вашей библиотеки. Однако это не делает вашу программу сверхпортативной, если вы не всегда знаете, где будет эта библиотека.

2) В случае, когда lib1 зависит от lib2, я фактически использовал SetCurrentDirectory (Windows, не уверен в эквиваленте Mac) в нативном коде, прежде чем он связывался с какой-либо из зависимых библиотек, и это, похоже, работало. Опять же, необходимо знать, где находятся другие библиотеки.

3) В Windows может вывести зависимые библиотеки в c: \ windows \ system32 и найти их.

Несколько полезных постов на аналогичную тему (специфично для Windows, но я думаю, что проблема та же):

http://www.realityinteractive.com/rgrzywinski/archives/000219.html http://www.velocityreviews.com/forums/t387618-jni-library-path.html

0 голосов
/ 25 марта 2010

Я нашел решение для MacOSX, основанное на идее (2) из ​​Stew:

Используя JarBundler для Mac (или задачу Ant с тем же именем), установите для переменной workingdirectory значение $ JAVAROOT и убедитесь, что ваши dylibs находятся в части Contents / Resources / Java в .app. Если вы сделаете это, динамический компоновщик найдет все библиотеки зависимостей, потому что это будет текущий каталог. Java также найдет оригинальный dylib (тот, у которого есть все зависимости) по той же причине.

Код муравья:

<target name="package_mac_app" depends="package_jar, compile_native" description="bundle the runnable jar into a Mac Application -- requires JarBundler ANT Task">
    <taskdef name="jarbundler" classname="net.sourceforge.jarbundler.JarBundler"/>
    <echo message="CREATING MAC .app EXECUTABLE"/>
    <jarbundler dir="${dist}"
      name="${appname}"
      mainclass="myPackage.myMainClass"
      icon="${icon_location}"
      jvmversion="1.5+"
      infostring="${appname}"
      shortname="${appshortname}"
      bundleid="${com.mycompany.mydepartment.myprogram}"
      jar="${run_jar_location}"
      workingdirectory="$JAVAROOT">
      <javafilelist dir="${dylib_location}" files="my-lib.dylib"/>
      <javafilelist dir="${dylib_location}" files="dependent-lib.dylib"/>
    </jarbundler>

</target>
...