1

我正在尝试开发一个名为 Sumerian (github.com/ryanthejuggler/Sumerian) 的程序,它是 Koper (koper.googlecode.com) 的一个分支。当我从 jar 中运行 Koper 时,它可以正常加载并且我可以使用该程序。我做了一些改进和重新编译,但现在它找不到存储libeinkfb.so. 我已将其复制到下面输出的第二行中列出的位置,但该程序仍然仅在我从 jar 中运行时运行。

我重构的一部分是将所有东西都放在包中;原始代码具有扁平结构。

另外,我查看了 JAR 清单;这是非常基本的,只定义版本和入口类。

我必须将 .so 文件放在哪里,以便我的 Java 程序可以看到它?

尝试运行我的代码:

[root@(none) bin]# java com.ramuller.sumerian.Sumerian
/qte/lib:lib::/usr/java/packages/lib/arm:/lib:/usr/lib
construct EInkFB
java.lang.UnsatisfiedLinkError: com.ramuller.sumerian.display.eink.EInkFB.open(Ljava/lang/String;)Ljava/nio/ByteBuffer;
        at com.ramuller.sumerian.display.eink.EInkFB.open(Native Method)
        at com.ramuller.sumerian.display.eink.EInkFB.<init>(EInkFB.java:113)
        at com.ramuller.sumerian.Sumerian.main(Sumerian.java:72)
construct Display width=600 height=800Creating SwingDisplay...
Exception in thread "main" java.awt.HeadlessException: 
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
        at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:207)
        at java.awt.Window.<init>(Window.java:535)
        at java.awt.Frame.<init>(Frame.java:420)
        at javax.swing.JFrame.<init>(JFrame.java:224)
        at com.ramuller.sumerian.display.SwingDisplay.<init>(SwingDisplay.java:21)
        at com.ramuller.sumerian.Sumerian.main(Sumerian.java:90)

之后立即运行 .jar,无需配置:

[root@(none) bin]# java -jar ../Koper.jar 
User directory: /mnt/sd/bin
/qte/lib:lib::/usr/java/packages/lib/arm:/lib:/usr/lib
construct EInkFB
The framebuffer device was opened successfully.
^C[root@(none) bin]# java -version
java version "1.7.0_06"
Java(TM) SE Runtime Environment (build 1.7.0_06-b24)
Java HotSpot(TM) Client VM (build 23.2-b09, mixed mode)

编辑我目前正在加载代码:

System.loadLibrary("einkfb");
4

2 回答 2

1

这行com.ramuller.sumerian.display.eink.EInkFB.open(Native Method)让我猜你重命名了包含本机方法的类的包,对吗?

使用 JNI,.so 文件中的方法名称和本地 Java 方法的名称需要完全匹配,包括方法的包名和类名。所以 Java 能够找到库(否则它会给出关于无法找到einkfb库的不同消息),但它无法找到该库中的方法。

您要么必须恢复类的重命名,要么还要重命名库中的函数,为此您必须重新编译它。

于 2012-12-09T20:19:07.673 回答
0

经过一番搜索,我发现您也可以使用显式加载库

System.loadLibrary("<name-of-lib>");

检查此链接以获取更多信息。它给出了关于相同的描述UnsatisfiedLinkError。从给定的链接

最常见的原因是传递给 loadLibrary 函数的名称的本机库命名不正确。传递给 loadLibrary 函数的字符串不能在字符串中包含文件扩展名,即 .dll 或 .so。对于所有平台,该字符串必须是 name 而不是 libname。在 Windows 上,本地库必须称为 name.dll,而在大多数 Unix 系统上,它必须称为 libname.so。

还要检查system.loadLibrary javadoc


编辑

您还可以在发出java执行命令时指定库路径,如下所示。将.so文件放在目录中并在此处引用,

 java -Djava.library.path=. com.ramuller.sumerian.Sumerian
于 2012-12-09T18:21:31.033 回答