Java 搜索一个本机库依赖于另一个本机库的路径
我正在使用JNA和Java,但我认为这个问题会影响任何本机到非本机的网桥 我有一个Java应用程序,它依赖于lib1.dylib,lib1.dylib依赖于lib2.dylib 我想把我的.app文件中的所有内容都放在Mac上。我可以轻松地将lib1.dylib放入其中,并设置java.classpath(或nativellibrary.addSearchPath())告诉JVM在哪里可以找到lib1.dylib。问题是,我不知道如何传达lib1.dylib的依赖项也在我提供的位置。结果是lib1加载正常,但由于lib2不在操作系统的库路径中,因此找不到它Java 搜索一个本机库依赖于另一个本机库的路径,java,macos,jna,Java,Macos,Jna,我正在使用JNA和Java,但我认为这个问题会影响任何本机到非本机的网桥 我有一个Java应用程序,它依赖于lib1.dylib,lib1.dylib依赖于lib2.dylib 我想把我的.app文件中的所有内容都放在Mac上。我可以轻松地将lib1.dylib放入其中,并设置java.classpath(或nativellibrary.addSearchPath())告诉JVM在哪里可以找到lib1.dylib。问题是,我不知道如何传达lib1.dylib的依赖项也在我提供的位置。结果是lib
有人知道我如何克服这个问题吗?我想在有大量共享库的大型项目中肯定会出现很多问题。我以前遇到过这个问题,今天又遇到了。您可以通过添加VM参数“-Djava.library.path=/path/to/other/libs”来绕过它,但我似乎记得Java只使用它来搜索初始库,然后使用系统路径来查找任何依赖项 我以前尝试过的几种解决方案: 1) 在加载库之前,在从属库上使用System.load(绝对路径)。但这并不能使你的程序具有超便携性,除非你总是知道程序库的位置 2) 在lib1依赖于lib2的情况下,我实际上在本机代码中使用了SetCurrentDirectory(Windows,不确定是否与Mac等效),然后才将其链接到任何依赖的lib,这似乎是可行的。同样,需要知道其他LIB在哪里 3) 在Windows上,可以在c:\Windows\system32中转储依赖库,并找到它们 关于类似主题的一些有用帖子(特定于Windows,但我认为问题是相同的):
我根据Stew(2)中的想法找到了MacOSX的解决方案: 使用Mac的JarBundler(或相同名称的Ant任务)将workingdirectory变量设置为$JAVAROOT,并确保dylib位于.app的Contents/Resources/Java部分。如果这样做,动态链接器将找到所有依赖项dylib,因为它将是当前目录。出于同样的原因,Java还会找到原始的动态库(具有所有依赖项的动态库) 蚂蚁代码:
<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>
谢谢!我去看看。很抱歉在我的问题中混淆了类路径和java库路径。(1) 或者(2)可能值得失去便携性。我试图避免(3),因为这会使安装程序变得非常复杂,需要根用户访问,有可能覆盖其他应用程序需要的libs的现有旧版本,等等:-\在调查这些选项之后,只有坏消息。(1) 不适用于JNA。显然,JNA并不关心Java之前是否加载了库,大概是因为它必须自己进行映射。然而,它将与JNI一起工作。(2) 将需要为不同的操作系统编写特殊代码,但最有问题的是,在UNIX中没有与dllmain等效的代码,也没有具体保证(据我所知)在完成依赖项查找之前将执行cwd开关。我认为除了(3)之外别无选择,我在这个问题上一直试图避免这一点。糟糕,很好。我可以在我的一个项目上尝试一下。它非常干净,仍然适合整个“拖放安装”。