Load java libraries from relative path - java

I've written a Java program that uses OpenCV library. So far, I executed the program with eclipse (and set the Jar location in eclipse properties).
This is a college final project. My instructor now wants to run the program in his computer. How can I generate a runnable jar(using Ant or using Java code) that will load the Java OpenCV jar from specific location (a directory that will be located in the executable Jar directory), that will work with Linux and Windows (I understood that linux uses a Jar file, and Windows uses a dll file)?
I've tried using:
String currentDir = System.getProperty("user.dir");
System.load(currentDir + "/path_to_jar/opencv-248.jar");
(let's ignore the fact that it will only work with linux) But when executing the jar, the following error occurs:
OpenJDK 64-Bit Server VM warning: You have loaded library /path_to_jar/opencv-248.jar which might have disabled stack guard. The VM will try to fix the stack guard now.
It's highly recommended that you fix the library with 'execstack -c ', or link it with '-z noexecstack'.
Exception in thread "main" java.lang.UnsatisfiedLinkError: /path_to_jar/opencv-248.jar: /path_to_jar/opencv-248.jar: invalid ELF header (Possible cause: endianness mismatch)
Any help would be highly appreciated.

Use the classpath option for your java executable.
If you're running OpenJDK read the manpage at http://linux.die.net/man/1/java-java-1.6.0-openjdk
You should be able to use something along the lines of:
java -jar yourapp.jar -cp ./path_to_jar/
Another option is to build a JAR which includes its own dependencies. Here are some examples I found using the search terms "java create jar include dependencies":
Using Maven
Using Eclipse

Related

Is it possible to get my SWT application to run anywhere just by adding the SWT binaries to the Java Build Path in Eclipse?

I made an SWT application using WindowBuilder in Eclipse. I exported the project as a runnable Jar File on Windows 10, then transferred the file to my Macosx machine, and I received this error,
$ java -jar Downloads/SWTApplication.jar
Exception in thread "main" java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons:
no swt-win32-4926r21 in java.library.path
no swt-win32 in java.library.path
Can't load library: /Users/myhomefolder/.swt/lib/macosx/x86_64/libswt-win32-4926r21.jnilib
Can't load library: /Users/myhomefolder/.swt/lib/macosx/x86_64/libswt-win32.jnilib
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:344)
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:256)
at org.eclipse.swt.internal.C.<clinit>(C.java:19)
at org.eclipse.swt.widgets.Display.<clinit>(Display.java:143)
at MainWindow.open(MainWindow.java:58)
at MainWindow.main(MainWindow.java:47)
I tried adding both the windows and mac versions of swt.jar file to the Java Build Path in Eclipse, and it did not work. Is there a way to get it to work just by adding the SWTs to the Java Build Path? Tell me if there are more steps to this process if there is.
I expected the program to run on my Mac machine, just like when I double click the Jar File on my Windows Machine, but it returned the error above.
Please bear with me since I'm relatively new to Java and SWT.

Issue running tensorflow with java

I am having some issues running tensorflow with java. I am using CUDA 8 with CuDNN 6.
I tried following the quickstart instructions located here: https://www.tensorflow.org/install/install_java and get the following error message when I attempt to run the example java program:
java -cp libtensorflow-1.4.0.jar:. -Djava.library.path=./jni HelloTF
Exception in thread "main" java.lang.UnsatisfiedLinkError: Cannot find TensorFlow native library for OS: linux, architecture: x86_64. See https://github.com/tensorflow/tensorflow/tree/master/tensorflow/java/README.md for possible solutions (such as building the library from source). Additional information on attempts to find the native library can be obtained by adding org.tensorflow.NativeLibrary.DEBUG=1 to the system properties of the JVM.
at org.tensorflow.NativeLibrary.load(NativeLibrary.java:75)
at org.tensorflow.TensorFlow.init(TensorFlow.java:66)
at org.tensorflow.TensorFlow.<clinit>(TensorFlow.java:70)
at org.tensorflow.Graph.<clinit>(Graph.java:258)
at HelloTF.main(HelloTF.java:8)
The jni directory contains the following:
libtensorflow_framework.so
libtensorflow_jni.so
LICENSE
I then tried installing the binaries from source as suggested here:
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/java/README.md
This is the output from setting: org.tensorflow.NativeLibrary.DEBUG=1
org.tensorflow.NativeLibrary: tryLoadLibraryFailed: /path/to/jni/libtensorflow_jni.so: libcublas.so.8.0: cannot open shared object file: No such file or directory
org.tensorflow.NativeLibrary: jniResourceName: org/tensorflow/native/linux-x86_64/libtensorflow_jni.so
org.tensorflow.NativeLibrary: frameworkResourceName: org/tensorflow/native/linux-x86_64/libtensorflow_framework.so
But I still get the same error message when I try and run the example Java program.
What am I doing wrong??
Any help would be greatly appreciated!
The error
Cannot find TensorFlow native library for OS: linux, architecture: x86_64.
is clearly stating that the library is not visible to your software.
To make it available to the Java class, try doing like that (in the same shell obviously):
export LD_LIBRARY_PATH=/the/absolute/path/to/your/library
java -cp libtensorflow-1.4.0.jar:. -Djava.library.path=./jni HelloTF
also ensure you're running the java command from the same directory which contains the /jni directory.
For those landing here and facing the same issue.
You are probably trying to run your program from eclipse. Then, you have to go to Run configurations > Arguments and pass this arguments:
Program arguments -> models/
images/example-400x288.jpg
VM Arguments -> -Djava.library.path=./jni
like in this screenshot:
When people (like myself) come from python to java world, everything is strange! here is how I solved my problem regarding all linking errors:
I assumed you already have simple hello Tensorflow project, explained here
Download and copy tensorflow JNI files to :/usr/lib/tensorflow
Download and copy desired version of tensorflow Lib jar file to: /usr/lib/tensorflow
Compile with java
Compile java file
javac -cp /usr/lib/tensorflow/libtensorflow-1.14.0.jar HelloTensorFlow.java
run java file:
java -cp /usr/lib/tensorflow/libtensorflow-1.14.0.jar:. -Djava.library.path=/usr/lib/tensorflow/ HelloTensorFlow
use MAVEN
First we should export LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=/usr/lib/tensorflow
Then run maven build command:
mvn -q compile exec:java
I hope it helps you

How to add an external library (OpenCV .jar file) to the Java build path from the command line (Unix)

I am trying to add the OpenCV library to the build path for my Java program from the terminal so that I can use a shell script to run the program on a bunch of image files sequentially. The .class files for my project are located in Documents/Programming/Ko/bin and the .jar file for the OpenCV library is located in Documents/Programming/opencv-2.4.10/build/bin. As suggested from a number of different questions on here, I have tried (while in the Ko/bin directory):
java -cp "/Users/jordan/Documents/Programming/opencv-2.4.10/build/bin/*:." Ko <image_name>
Which produces the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java2410 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1119)
at Ko.main(Ko.java:37)
So the program runs into an issue at line 37. This line is:
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
I added this line after running into issues loading the OpenCV library in Eclipse, from the advice of another question on here, although I'm not exactly sure what it does or why it is necessary. When I try commenting out this line I get a similar error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.opencv.highgui.Highgui.imread_0(Ljava/lang/String;I)J
at org.opencv.highgui.Highgui.imread_0(Native Method)
at org.opencv.highgui.Highgui.imread(Highgui.java:309)
at Ko.main(Ko.java:39)
This time at line 39, which logically is the first time I call a method from the OpenCV library.
As far as I can tell, the way I'm writing the java -cp ... command is identical to what has worked for others from the questions I've read on here. If anyone could tell me where I'm going wrong and could explain why the call to System.loadLibrary() is necessary in this particular case when in other cases of importing libraries it is not, it would be greatly appreciated.
The problem was that the command line had no knowledge of where the native libraries were on disk (i.e. the opencv2.so file). After adding an extra flag to the command and specifying the path to the native libraries, the program executed correctly:
java -D'java.library.path=<path to native libraries>' -cp '<path to Ko.class>:<path to opencv-2.4.x jar file>' Ko <path to input image file>
The first flag (-D) sets the java.library.path variable to the native libraries specific to this application so that the JRE knows where the jar file is linking to.
The second flag (-cp) sets the class path (which directories the JRE looks in for files to run). These directories are separated by colons (:) on OSX/Linux/Unix and separated by semicolons (;) on Windows.
Hope this helps anyone who runs across this problem in the future.

Executing Java application that makes a JNI call, with eclipse, fails with UnsatisfiedLinkError: Can't find dependent libraries

I have a Java program that calls a function in a JNI library. The JNI code statically loads another shared library.
When executing the Java application using Eclipse, I get an error java.lang.UnsatisfiedLinkError: ... Can't find dependent libraries
But, if i execute the same command in commandline, the program works fine. What am I doing wrong in Eclipse?
I made sure to go to Debug View -> Processs -> Process Properties to get the same command string and same working directory as Eclipse execution.
Here is a PD procedure that might help you identify the problem.
Add the following to your program to identify the differences in the arch and load paths between the two runtime environments. Investigate any differences in path/arch.
System.out.println(System.getProperty("java.library.path"));
System.out.println(System.getProperty("sun.arch.data.model"));
You can use the dumpbin.exe utility to identify the dependencies needed by the DLL that is being loaded.
Make sure the dependencies exist.
Example usage:
C:> dumpbin /imports your.dll
Dump of file your.dll
File Type: DLL
Section contains the following imports:
**KERNEL32.dll**
You can use the where.exe command to find the location of the dependencies.
Example usage:
C:>where KERNEL32.dll
C:\Windows\System32\kernel32.dll
If you see:
C:>where KERNEL32.dll
INFO: Could not find files for the given pattern(s)
Investigate why the dependent DLL is not on the path.
You can use the dumpbin.exe command to check 64bit vs 32bit.
Example:
C:>dumpbin /headers yourd.dll
Dump of file yourd.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (x86) <-- 32bit DLL
C:>dumpbin /headers yourd.dll
Dump of file yourd.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
8664 machine (x64) <-- 64bit DLL
Investigate any 32bit vs 64bit mismatches between main/dependent. If your JVM is 32bit, you need to use 32bit DLLs. If your JVM is 64bit, you need to use 64bit DLLs. ( It is okay to run a 32bit JVM on a 64bit OS but the JNI DLLs must be 32bit ( DLLs match the JVM not the OS ).

Cannot execute Java app on Vista Business - "Cannot find the main class... Program will exit"

I have written a Java GUI app (using Netbeans 6.7) requiring Java 1.6. I successfully run it on my XP PC and also my Mac OSX (10.5.7).
My client is running Vista Business, and cannot run the application by double clicking the jar file. He can execute it from the command line: "javaw -jar ..." The error received is: "Cannot find the main class... Program will exit".
I've asked the client to do the following:
install the latest JRE
run JarFix
I've verified that:
JRE is installed in correct location
jar file association is correct
application works (as I have tested it on XP and Mac OSX, and the client can run it from the command line)
Any ideas on what else I can investigate? Note, Netbeans created the main jar file, and also a lib directory with a couple of other Jarfiles. I've unzipped the jarfile and examined the manifest file (which looks good). The correct main class is also within the app's jarfile.
Does the client need to be careful as to where the application is executed from in Vista?
Thanks very much.
Prembo
Does exactly the same JAR file work on other operating systems?
Is the manifest file (META-INF/MANIFEST.MF) in the JAR file correct? One catch to watch out for is that the manifest file MUST end with an empty line; if it doesn't, the last line in the manifest file will be ignored. So, for example, if the last line in your manifest file is something like this:
Main-Class: com.mypackage.MyProgram
and it is not followed by an empty line, then Java will ignore the line and it will not be able to find the main class of the program.
See Sun's Java Tutorial about deploying Java programs in JAR files for exact details about how to package your application in a JAR; it also contains the warning about the manifest file needing to end with an empty line.
Also, double-check if the right version of Java is used. Are you using the exact same version of Java as on Windows XP? Try:
java -version
to see which Java version is being used.
I'm running Vista Enterprise and have very little differences between it and other Windows versions (with regards to Java).
Here are some random ideas that may or may not work:
Have you tried: right clicking on the Jar -> Open with -> Java(TM) Platform SE Binary
Could it be permissions related? (probably not since it runs via the command line)
Have you tried it with UAC off? (UAC sandboxes java apps, and they can't write to certain locations like Program Files)
Did you make sure they have the same files as you in JAVA_HOME/lib/ext/
you could try setting environment variables:
JAVA_HOME=<your_java_home>
CLASSPATH=.
PATH=<your_java_home>\bin
Sometimes JDK needs to be installed separately,along with the net beans IDE. If you have jdk installed then you can try checking for classpath,path in the environmental variables.

Categories