Java中的本机库位置

时间:2012-12-09 18:12:31

标签: java java-native-interface

我正在努力开发一个名为Sumerian(github.com/ryanthejuggler/Sumerian)的程序,这是Koper的一个分支(koper.googlecode.com)。当我从jar运行Koper时,它加载正常,我可以使用该程序。我做了一些改进和重新编译,但现在它找不到存储在libeinkfb.so中的 einkfb 库。我已将其复制到下面输出第二行中列出的位置,但程序仍然只在我从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");

2 个答案:

答案 0 :(得分:1)

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

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

您必须还原该类的重命名,或者还要重命名库中的函数,您必须重新编译它。

答案 1 :(得分:0)

经过一番搜索后,我发现您还可以使用

显式加载库
System.loadLibrary("<name-of-lib>");

查看this link了解详情。它给出了关于相同UnsatisfiedLinkError的描述。来自给定的链接

  

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

同时检查system.loadLibrary javadoc


修改

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

 java -Djava.library.path=. com.ramuller.sumerian.Sumerian