Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在linux中调试java system.loadlibrary错误?_Java_Eclipse_Java Native Interface - Fatal编程技术网

如何在linux中调试java system.loadlibrary错误?

如何在linux中调试java system.loadlibrary错误?,java,eclipse,java-native-interface,Java,Eclipse,Java Native Interface,我有一个Java程序,它通过我试图在Linux上运行的JNI调用C代码。外部代码由两个.so文件组成:一个用于JNI绑定(使用swig构建),另一个用于实际函数。我将两个库放在同一个目录中,并且LD_LIBRARY_路径设置正确。从命令行运行时,ldd不会报告任何问题,但当我在Eclipse编辑器的“运行配置”对话框中将LD_LIBRARY_PATH设置为相同的值并尝试执行该程序时,它会出现以下错误: java.lang.UnsatifiedLinkError:[库的路径]/[JNI绑定库]。s

我有一个Java程序,它通过我试图在Linux上运行的JNI调用C代码。外部代码由两个.so文件组成:一个用于JNI绑定(使用swig构建),另一个用于实际函数。我将两个库放在同一个目录中,并且LD_LIBRARY_路径设置正确。从命令行运行时,ldd不会报告任何问题,但当我在Eclipse编辑器的“运行配置”对话框中将LD_LIBRARY_PATH设置为相同的值并尝试执行该程序时,它会出现以下错误:

java.lang.UnsatifiedLinkError:[库的路径]/[JNI绑定库]。so:[实际代码库]。so:无法打开共享对象文件:没有这样的文件或目录

这使我相信JNI包装器库已成功加载,但当该库尝试加载包含实际代码的库时,就会失败。有没有办法进一步调试


我将进一步注意到,这个问题发生在eclipse编辑器本身,我还没有尝试将代码打包到jar中,并在独立的jvm实例中运行它。

您可以尝试
-Djava.library.path=actual.so
在命令行参数中


在windows上,我遇到了与第三方库类似的问题,该库使用JNI包装DLL作为DLL。我的项目在lib目录中有DLL,因此我将lib添加到路径中(例如,
PATH=%PATH%;./lib
环境变量,并且一切都开始工作。

据我所知,Eclipse不使用LD_LIBRARY_路径。 设置正确的本机库路径的最简单方法是转到 项目属性->Java构建路径->库 然后展开JRE系统库条目或(如果可用) 使用本机库的Jar文件,
选择“本机库位置”,然后单击“编辑…”并选择库所在的文件夹。实际上,它设置了-Djava.Library.path变量,因此如果从eclipse外部启动程序,则必须在命令行中包含该变量。

我认为问题在于调用System.loadLibrary(String)使用loadLibrary(“foo”)将在java.LIBRARY.PATH中查找名为libfoo.so的内容。如果未找到名为libfoo.so的内容,则会出现此错误

现在,如果您只是设置LD_LIBRARY_路径,那么链接器将自动拾取您想要的本机符号,因此您不需要设置-Djava.LIBRARY.PATH

根据我在gdal项目中使用swig的经验,这个错误实际上是无害的,因为LD_LIBRARY_路径已经设置好了,所以它可以正常工作

我建议使用-Djava.library.path并显式调用loadLibrary,原因是如果您决定使用webstart部署应用程序,则需要显式调用loadLibrary以获取本机libs


当我使用eclipse时,我遵循Daff给出的说明,在构建路径的Libraries选项卡中编辑jar下的本机库。再说一次,这只是在封面下设置java.library.Path。

您可能只需要在run config对话框中找到正确的位置,以放置-Djava.library.Path=…opti一方面,我认为您希望在“vm参数”中定义-D在arguments选项卡上,而如果您想定义环境选项卡上的LD_LIBRARY_路径,Eclipse会很高兴地让您将内容放在您认为它们的含义不同的地方。无论如何,我以前就以这种方式使用过库,如果有机会,我会在这里查找我所做的并编辑我的答案


另一件要尝试的事情是使用LD_DEBUG。您可以将环境变量LD_DEBUG设置为各种类型(全部试用),然后linux加载程序将泄露各种有用的信息,比如应用程序试图加载什么、它在哪里查找东西等等。当然,这预先假定您从命令行启动eclipse,因此您可以设置env vars并查看加载程序诊断;但就系统而言,当您运行应用程序时从eclipse内部看,您的应用程序只是eclipse正在做的事情,因此可以通过这种方式查看任何库加载行为。

您的两个库是否还依赖于其他库?如果是,您需要确保JVM也可以访问它们

请注意,手动设置“-Djava.library.path”似乎会删除默认的库路径

因此,使用以下代码:

public class LibTest {
    public static void main(String[] args) {
        String property = System.getProperty("java.library.path");
        StringTokenizer parser = new StringTokenizer(property, ":");
        while (parser.hasMoreTokens()) {
            System.err.println(parser.nextToken());
        }
    }
}
使用Java 1.6.0_14输出从eclipse启动:

/opt/java/jre/lib/i386/client
/opt/java/jre/lib/i386
/opt/java/jre/../lib/i386
/opt/java/jre/lib/i386/client
/opt/java/jre/lib/i386
/usr/lib/xulrunner-devel-1.9.0.11
/usr/lib/xulrunner-devel-1.9.0.11
/usr/java/packages/lib/i386
/lib
/usr/lib
但是当我设置JVM参数“-Djava.library.path=/tmp/”时,我只得到:

/tmp/
如果您手动设置java.library.path,这可以解释为什么ldd可以从命令行工作,而您的.so不能从eclipse/java工作

您可以尝试不设置java.library.path,而使用System.load作为指向您的库的绝对路径,而不是调用System.loadLibrary。这可能允许JVM找到您的.so,并在搜索其依赖项时仍使用默认路径


当然,如果这没有用,那么您也可以尝试使用“-verbose:jni”打开jni调试输出在命令行上。这可能会为您提供一些问题的线索。

是的,LD\u LIBRARY\u路径对我有效。

添加此答案可能对AIX机器有用。我们需要设置LIBPATH环境变量,而不是LD\u LIBRARY\u PATH