Reputation: 3637
I'm trying to work on a program I call Sumerian (github.com/ryanthejuggler/Sumerian), a fork of Koper (koper.googlecode.com). When I run Koper from a jar, it loads fine and I can use the program. I did a little bit of improving and recompiled, but now it cannot find the einkfb library, stored in libeinkfb.so
. I've copied this to the locations listed on the second line of the output below, but the program still only runs when I run it from the jar.
Part of my refactoring was placing everything in packages; the original code had flat structure.
Also, I looked at the JAR manifest; it's very basic, defining only version and entry class.
Where do I have to place the .so file so my Java program can see it?
Attempting to run my code:
[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)
Running the .jar immediately after, no configuration:
[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)
edit I'm currently loading the code with:
System.loadLibrary("einkfb");
Upvotes: 1
Views: 1781
Reputation: 11423
The line com.ramuller.sumerian.display.eink.EInkFB.open(Native Method)
let's me guess that you renamed the package of the class that contains native methods, is this right?
With JNI, the names of the methods in the .so file and the names of the native Java methods need to match exactly, including package and class name of the method. So Java is able to find the libray (otherwise it would give a different messages about not being able to find the einkfb
library), but it can't find the methods in this library.
You either have to revert the renaming of the class, or also rename the functions in the library, for which you have to recompile it.
Upvotes: 1
Reputation: 13717
After some searching, I found that you can also explicitly load the library using
System.loadLibrary("<name-of-lib>");
Check this link for more info. It gives a description regarding the same UnsatisfiedLinkError
. From the given link
The most common cause for this is an incorrect naming of the native library for the name passed to the loadLibrary function. The string passed to the loadLibrary function must not include the file extension name in the string, that is .dll or .so. The string must be name and not libname for all platforms. On Windows the native library must then be called name.dll and on most Unix systems it must be called libname.so.
Also check the system.loadLibrary javadoc.
You can also specify the library path while issue the java
execution command as shown below. Place the .so
file in a directory and reference it here,
java -Djava.library.path=. com.ramuller.sumerian.Sumerian
Upvotes: 0