搜索一个本机库依赖另一个本机库的路径

时间:2010-03-24 20:06:41

标签: java macos jna

我正在使用JNA和Java,但我认为这个问题会影响任何本地到非本地的桥梁。

我有一个依赖lib1.dylib的Java应用程序,而lib1.dylib依赖于lib2.dylib。

我想把我的.app文件中的所有内容都放在Mac上。我可以轻松地将lib1.dylib放入其中并设置java.classpath(或NativeLibrary.addSearchPath())以告诉JVM在哪里可以找到lib1.dylib。问题是,我不知道如何沟通lib1.dylib的依赖关系也在我提供的位置。结果是lib1加载正常,但是找不到lib2,因为它不在操作系统的库路径中。

任何人都知道如何克服这个问题?我想在包含大量共享库的大型项目中必须有很多。

2 个答案:

答案 0 :(得分:2)

我之前遇到过这个问题,今天又遇到了这个问题。您可以通过添加VM参数“-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

答案 1 :(得分:0)

我已经根据Stew中的(2)中的想法找到了MacOSX的解决方案:

使用Mac的JarBundler(或同名的Ant任务)将workingdirectory变量设置为$ JAVAROOT,并确保您的dylib位于.app的Contents / Resources / Java部分。如果这样做,动态链接器将找到所有依赖项dylib,因为它将是当前目录。由于同样的原因,Java也会找到原始的dylib(具有所有依赖关系的dylib)。

Ant代码:

<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>