Java runtime error with JNI - java

I am trying to build and run an example jni program. The program is just a sample helloworld program. I did not write it but I assume that it works. I am running this on Linux. There are four files.
HelloNative.c
HelloNative.h
HelloNative.java
HelloNativeTest.java
To build the files, I did
gcc -I/myDir/jdk/include -I/myDir/jdk/include/linux -fPIC -c HelloNative.c
gcc -shared -o HelloNative.so HelloNative.o
java *java
Here is the result of the build
HelloNative.c
HelloNative.h
HelloNative.o
HelloNativeTest.class
HelloNative.class
HelloNative.java
HelloNative.so
HelloNativeTest.java
Then I did
setenv LD_LIBRARY_PATH /myDir/myExample:${LD_LIBRARY_PATH}
java HelloNativeTest
I got the following error
Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1734)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at HelloNative.<clinit>(HelloNative.java:9)
at HelloNativeTest.main(HelloNativeTest.java:8)
I checked the LD_LIBRARY_PATH and the HelloClassTest and HelloNative.so, they were all there. I tried to specify the -CLASSPATH also, but that did not seem to matter.
Does anyone have any ideas ?

Do the following, where X="HelloNative".
Give the library a filename following a system-dependent standard. On Linux, name your library libX.so.
Set the java.library.path System property to the directory containing your library.
Call System.loadLibrary("X") where "X" is the cross-platform part of the library name above.
You named your library HelloNative.so; change it to libHelloNative.so.
From http://download.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp679:
The argument to System.loadLibrary is
a library name chosen arbitrarily by
the programmer. The system follows a
standard, but platform-specific,
approach to convert the library name
to a native library name. For example,
a Solaris system converts the name
pkg_Cls to libpkg_Cls.so, while a
Win32 system converts the same pkg_Cls
name to pkg_Cls.dll.
If you use OSGi in the future, there's an alternative to setting java.library.path.

You can also try by setting the java.library.path:
java -Djava.library.path=/myDir/myExample HelloNativeTest

Did you do a System.loadLibrary() from Java?

Related

opencv native library cannot be found

I am using an exmplae from here to apply face recognition using opencv. I have extracted opencv at C:\. However, after running the provided example cod in Java, I get the following exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java341 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1119)
at detectingfaceinanimage.DetectingFaceInAnImage.main(DetectingFaceInAnImage.java:23)
I used System.out.println(System.getProperty("java.library.path")); to locate path for the java library but I have received numerous paths. Can you let me know how to fix thsi issue? (For Windows platform)
To solve this issue, needed to copy the .dll file from C:\opencv\build\java\x64 (as I am running a 64 bit operating system) into C:\Program Files\Java\jdk1.8.0_31\bin.
You should do these things:
Add the OpenCV Jar file in your project classpath (I think you
already did it)
Locate the OpenCV DLL file location where you extracted it, maybe it
looks like this:
C:\opencv\build\x64\vc15\bin
Then add this path in your system environment variable
In the end, restart your IDE (not your computer), and yes it is that!
Good Luck!!

File missing from java.library.path

I am building an app to get NMEA GPS data, with serial port communication via RXTX.
On my Mac it runs great. When I try to run it on my Rasp Pi, it throws the error:
no rxtxSerial in java.library.path thrown while loading gnu.io.RXTXCommDriver
On the Mac, I see that if I move /Library/Java/Extensions/librxtxSerial.jnilib it too throws the same error.
My question is: On my RasbPi, do I need to add this rxtxSerial file somewhere to a folder (perhaps within the JVM?), or should it be packaged up with the runnable jar when I export. Is my problem on my Mac, or on my RasbPi?
Thanks
You can install this library on the Raspberry Pi via the normal package installation method.
Just type:
sudo apt-get install librxtx-java
Now you can start the jar like this:
java -Djava.library.path=/usr/lib/jni -cp /usr/share/java/RXTXcomm.jar -jar your.jar
The error means that a native library named rxtxSerial cannot be found. You need to have a native library for the Raspberry Pi with that name, and set the system property java.library.path so that it points to the directory that contains the native library. That means you have to start your Java program with the -D option, for example:
java -Djava.library.path=/some/dir com.mypackage.MyProgram
where /some/dir is the directory that contains the native library.
You'll have to find out if there is a native library that is suitable for the Raspberry Pi for the RXTX library that you are trying to use.

Java Path zeromq setting

I am using MAC OSX
I already follow the instruction on 0mq official site to install
when i compile it , i dont get any error.
But when i run the following command
java -classpath /Users/john/jzmq/ -cp $(lein classpath) storm.starter.WordCountTopology
I got the following error.
java.lang.UnsatisfiedLinkError: no jzmq in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1878)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1087)
at org.zeromq.ZMQ.<clinit>(ZMQ.java:34)
at storm.starter.spout.RandomSentenceSpout.nextTuple(RandomSentenceSpout.java:39)
at backtype.storm.daemon.executor$fn__3985$fn__3997$fn__4026.invoke(executor.clj:502)
at backtype.storm.util$async_loop$fn__465.invoke(util.clj:377)
at clojure.lang.AFn.run(AFn.java:24)
at java.lang.Thread.run(Thread.java:724)
My setting
$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home
I also have zmq.jar under
/usr/local/lib and
/usr/local/share/java
I read through all the google search I can found. Still no crew why my one is not working
In addition to setting the JAR classpath, you need to specify where the jzmq .so library files reside. Did you build zmq, libzmq, and jzmq exactly as described in the directions? If so, you should see the .so library files in /usr/local/lib and zmq.jar in /usr/local/share/java, confirm that, then logout/login based on this, then try this:
java -Djava.library.path=/usr/local/lib -cp "/usr/local/share/java/zmq.jar:/Users/john/jzmq/<your jar here>" storm.starteer.WordCountTopology
Hope it helps

JNI: Problems compiling 64-bit native libraries

I compiled a native DLL file on Windows (64-bit) with GCC flags -c and -o Name.dll.
When I did System.load("fullpahhere"), I get this error:
java.lang.UnsatisfiedLinkError: RenderControl.dll: %1 is not a valid Win32 application
If I recompile adding a blank main() method to the C source and removing the -c flag, it then fails with an UnsatisfiedLinkError that says it can't load a 32 bit DLL on a 64 bit machine.
Why is Java calling a DLL with no main method invalid? Doesn't that ruin the whole point of DLL files and the JNI?
Update
I fixed the main() issue. This GCC invocation setup works:
gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I "C:\Program Files\Java\jdk1.6.0_32\include" -I "C:\Program Files\Java\jdk1.6.0_32\include\win32" -shared *.c -o lib.dll
I still need to figure out the JVM Architecture problem, however.
Where can I find a MinGW installation that is capable of compilnig 64 bit code? It seems my standard MinGW install only does 32 bit.
If I can get my hands on that, how do I decide which library to load in Java? Is there a System property that shows the JVM arch (NOT the OS arch)?
If you use the MinGW32 compiler, you cannot produce 64-bit code. This is something that is most likely intentional. Similar issues with other people I quickly looked up seem to suggest that you're trying to use a 32-bit native binary with 64-bit java.
Try compiling with mingw-w64 and see if that allays the problem.
There's also the possibility that your library simply isn't in the library path and that it's not being found even though you're giving System.load the full path, in which case you should make sure that your DLL is in the correct location for native libraries.
Check out http://tdm-gcc.tdragon.net/, to download TDM-GCC which gives an easy installation on Windows for MinGW-w64 referenced above. You can use the following code to generate a 64-bit dll after installint TDM-GCC.
"C:\MinGW64\bin\gcc.exe" -m64 -c -I"C:\Program Files\Java\jdk1.6.0_26\include" -I"C:\Program Files\Java\jdk1.6.0_26\include\win32" HelloWorld.c
It is the "-m64" which makes it 64 bit. This is run from the same directory as the HelloWorld.c C Code Source File. This generates the HelloWorld.o C Code Object File in the same directory as run..

UnsatisfiedLinkError when using JNI?

I want to call a C program from Java program using JNI in linux ubuntu.
I am new to this and I have tried the sample program given in http://www.ibm.com/developerworks/java/tutorials/j-jni/section2.html
. I have already created the .java, .h , .c and .so files. But when i tried to run the program I am getting the following error.
Exception in thread "main" java.lang.UnsatisfiedLinkError: no Sample1 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at Sample1.main(Sample1.java:13)
This exception is indicating that the .so is not available to the JVM.
Adding the directory where the .so exists to the LD_LIBRARY_PATH will resolve this. If the .so depends on other .so libraries the directories where these .so exist will also need added to LD_LIBRARY_PATH.
I've just tried to get the same sample to work on my CentOS and got the same error as you. As already answered, JVM failed to find the so file needed. I succeeded to get it to work by following the steps below using gcc:
$ javac Sample1.java
$ javah Sample1
$ # Include paths must also be specified using -I option in the following gcc command line!
$ gcc -shared -I...snip... Sample1.c -o libSample1.so
$ # Library path for libSample1.so must also be specified!
$ java -Djava.library.path=...path/to/libSample1.so... Sample1
If you omit the "lib" prefix of the shared library, JVM fails to find it for some reason.
I don't know why. I am not familiar with the naming convention of shared libraries in Linux.
I hope this post could help.

Categories

Resources