eclipse 如何在 linux 中调试 java system.loadlibrary 错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1010503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to debug a java system.loadlibrary error in linux?
提问by user98166
I have a Java program that is calling C code through JNI that I'm attempting to run on Linux. The external code consists of two .so files: one for the JNI bindings (built with swig) and the other with the actual functions. I have the two libraries in the same directory and LD_LIBRARY_PATH is set correctly. ldd reports no problems when running from the command line, but when I set the LD_LIBRARY_PATH to the same value in the "run configurations" dialog in the Eclipse editor and attempt to execute the program, it gets the following error:
我有一个 Java 程序,它通过 JNI 调用 C 代码,我试图在 Linux 上运行该程序。外部代码由两个 .so 文件组成:一个用于 JNI 绑定(使用 swig 构建),另一个用于实际功能。我在同一目录中有两个库,并且 LD_LIBRARY_PATH 设置正确。从命令行运行时 ldd 报告没有问题,但是当我在 Eclipse 编辑器的“运行配置”对话框中将 LD_LIBRARY_PATH 设置为相同的值并尝试执行该程序时,它收到以下错误:
java.lang.UnsatisfiedLinkError: [path to libraries]/[JNI binding library].so: [actual code library].so: cannot open shared object file: No such file or directory
java.lang.UnsatisfiedLinkError: [库路径]/[JNI 绑定库].so: [实际代码库].so: 无法打开共享对象文件: 没有那个文件或目录
This leads me to believe that the JNI wrapper library is loaded successfully, but there is a failure when that library attempts to load the library containing the actual code. Is there any way to debug this further?
这让我相信 JNI 包装器库已成功加载,但是当该库尝试加载包含实际代码的库时会失败。有什么办法可以进一步调试吗?
I will further note that this problem is happening in the eclipse editor itself and that I haven't attempted to package the code into a jar and run it within a free-standing jvm instance.
我将进一步指出,这个问题发生在 eclipse 编辑器本身中,我没有尝试将代码打包到 jar 中并在独立的 jvm 实例中运行它。
回答by carrino
I think the issue is with the call to System.loadLibrary(String) and using LD_LIBRARY_PATH. Using loadLibrary("foo") will look in your java.library.path for something named libfoo.so. If nothing named libfoo.so is found you will get this error.
我认为问题在于调用 System.loadLibrary(String) 并使用 LD_LIBRARY_PATH。使用 loadLibrary("foo") 将在您的 java.library.path 中查找名为 libfoo.so 的内容。如果未找到名为 libfoo.so 的任何内容,您将收到此错误。
Now if you just set up the LD_LIBRARY_PATH, the native symbols you want will automatically be picked up by the linker, so you don't need to set up -Djava.library.path.
现在,如果您只是设置 LD_LIBRARY_PATH,链接器会自动选取您想要的本机符号,因此您无需设置 -Djava.library.path。
In my experience with swig in the gdal project, this error is actually harmless and since the LD_LIBRARY_PATH is set up, this will work fine.
根据我在 gdal 项目中使用 swig 的经验,此错误实际上是无害的,并且由于 LD_LIBRARY_PATH 已设置,因此可以正常工作。
I would recommend using -Djava.library.path and calling loadLibrary explitly, the reason being that if you ever decide to deploy your app with webstart, you will explicitly need to call loadLibrary to get your native libs picked up.
我建议使用 -Djava.library.path 并显式调用 loadLibrary,原因是如果您决定使用 webstart 部署您的应用程序,您将明确需要调用 loadLibrary 来获取您的本机库。
When I use eclipse I follow the instructions that Daff gave where you edit the native library under the jar in the Libraries tab in the Build Path. Just to mention again, this just sets java.library.path under the covers.
当我使用 eclipse 时,我按照 Daff 给出的说明在构建路径的库选项卡中的 jar 下编辑本机库。再次提一下,这只是在幕后设置 java.library.path 。
回答by JustJeff
It may be that you just have to find the right place on the run config dialog to put the -Djava.library.path=... option. Offhand I think you want -D defines in the "vm arguments" on the arguments tab, whereas if you want to define LD_LIBRARY_PATH that goes on the environment tab. Eclipse will merrily let you put things in places where they won't mean what you think they mean. Anyway, I've used libraries this way before and if I get a chance I will look up what I did and edit my answer here.
可能您只需要在运行配置对话框中找到正确的位置来放置 -Djava.library.path=... 选项。我认为您希望 -D 在参数选项卡上的“vm 参数”中定义,而如果您想定义环境选项卡上的 LD_LIBRARY_PATH。Eclipse 会很高兴地让你把东西放在它们不代表你认为它们的意思的地方。无论如何,我以前以这种方式使用过库,如果有机会,我会查找我所做的并在此处编辑我的答案。
Another thing to try is to play with LD_DEBUG. You can set the environment variable LD_DEBUG to various things (try ALL), and then the linux loader will divulge all sorts of useful information about what an application is trying to load, whereit's looking for things, etc. Of course, this pre-supposes you launch eclipse from a command line, so you can both set the env vars and see the loader diagnostics; but as far as the system is concerned, when you run your app from inside eclipse, your app is just something eclipse is doing, so any library loading behavior can be seen in this way.
另一件要尝试的事情是玩 LD_DEBUG。您可以将环境变量 LD_DEBUG 设置为各种东西(尝试 ALL),然后 linux 加载器会透露各种有用的信息,例如应用程序正在尝试加载什么、它在何处寻找东西等。当然,这预假设您从命令行启动 eclipse,因此您可以设置环境变量并查看加载程序诊断信息;但是就系统而言,当您从 eclipse 内部运行您的应用程序时,您的应用程序只是 eclipse 正在做的事情,因此可以通过这种方式看到任何库加载行为。
回答by Aaron
Are there any other libraries that your two libraries depend on? If so, you need to make sure they are also accessible to the JVM.
您的两个库是否依赖于其他库?如果是这样,您需要确保它们也可以被 JVM 访问。
Be aware, manually setting "-Djava.library.path" seems to erase the default library path.
请注意,手动设置“-Djava.library.path”似乎会擦除默认库路径。
So with the following code:
所以使用以下代码:
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());
}
}
}
Launched from eclipse with Java 1.6.0_14 outputs:
从带有 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
But when I set the JVM arg "-Djava.library.path=/tmp/" I only get:
但是当我设置 JVM 参数“-Djava.library.path=/tmp/”时,我只得到:
/tmp/
If you are manually setting java.library.path this may explain why ldd works from the command line but your .so does not from eclipse/java.
如果您手动设置 java.library.path,这可能解释了为什么 ldd 可以从命令行运行,而您的 .so 不能从 eclipse/java 运行。
You can try not setting java.library.path and use System.load with the absolute path to your library instead of calling System.loadLibrary. This may allow the JVM to find your .so and still use the default path when searching for its dependencies.
您可以尝试不设置 java.library.path 并使用 System.load 和库的绝对路径,而不是调用 System.loadLibrary。这可能允许 JVM 找到您的 .so 并在搜索其依赖项时仍然使用默认路径。
Of course, if this is no use then you can also try turning on jni debug output with "-verbose:jni" on the command line. This may give you some clues to the problem.
当然,如果这没有用,那么您也可以尝试在命令行上使用“-verbose:jni”打开 jni 调试输出。这可能会为您提供一些解决问题的线索。
回答by MSSV
Yes the LD_LIBRARY_PATH worked for me
是的 LD_LIBRARY_PATH 对我有用
回答by Dungeon Hunter
Adding this answer may be it can be useful In AIX Machines we need to setup LIBPATH environment variable instead of LD_LIBRARY_PATH.
添加此答案可能很有用 在 AIX 机器中,我们需要设置 LIBPATH 环境变量而不是 LD_LIBRARY_PATH。
回答by akarnokd
You could try -Djava.library.path=actual.so
in command line parameters perhaps?
你可以试试-Djava.library.path=actual.so
命令行参数吗?
On windows, I had similar problems with a 3rd party library, which used a JNI wrapper DLL for its DLLs. My project had the DLL in the lib directory so I added lib to the PATH (e.g. PATH=%PATH%;./lib
environment variable and everything started working.
在 Windows 上,我在使用 JNI 包装器 DLL 的 3rd 方库时遇到了类似的问题。我的项目在 lib 目录中有 DLL,所以我将 lib 添加到 PATH (例如PATH=%PATH%;./lib
环境变量,一切都开始工作。
回答by Daff
As far as I know the Eclipse doesn't use the LD_LIBRARY_PATH. The easiest way to set up the right native library path is to go to Project properties -> Java Build Path -> Libraries Then expand either the JRE System Library entry or (if available) the Jar File that uses you native Library, choose "Native Library Location" then click "Edit..." and choose the folder your libraries are in. Actually it does set the -Djava.library.path variable so you have to include this in your command line if you start your program from outside eclipse.
据我所知,Eclipse 不使用 LD_LIBRARY_PATH。设置正确的本机库路径的最简单方法是转到项目属性 -> Java 构建路径 -> 库然后展开 JRE 系统库条目或(如果可用)使用本机库的 Jar 文件,选择“本机库位置”然后单击“编辑...”并选择您的库所在的文件夹。实际上它确实设置了 -Djava.library.path 变量,因此如果您从 eclipse 外部启动程序,则必须将其包含在命令行中.