AIX: "java.lang.UnsatisfiedLinkError" but the library exists - java

I'm using JNI to call a shared library named "libmy_jni.so" from my java code. Those are working good without any problem in other OS's but in AIX, I see the following error. I've checked that the LIBPATH and LD_LIBRARY_PATH(in case) are set correctly and matched x86 module with 32bit java(and x64 with 64bit java).
Exception in thread "Thread-1" java.lang.UnsatisfiedLinkError: my_jni (No such file or directory)
The java code loading the library is,
File sofile = new File("libmy_jni.so");
if(!sofile.exists())
{
System.out.println("can't find the moudle.");
System.exit(1);
}
System.loadLibrary("my_jni");
As I know, the most cases causing the error above are incorrect library path or unmatched 32/64bit architecture. But in my case I don't see what could be the reason.
>>file libmy_jni.so
libmy_jni.so: 64-bit XCOFF executable or object module not stripped

Related

Problem connecting Java and Prolog with JPL

I wanted to connect Java and Swi Prolog together using JPL.
When I added the library to my project on Intellij the code compiled and when I tried to run a query I got a runtime error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jpl in java.library.path: [C:\Program Files\Java\jdk-12\bin, C:\WINDOWS\Sun\Java\bin, C:\WINDOWS\system32, C:\WINDOWS, c:\swipl\bin, ${env_var:PATH}, .]
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2660)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:827)
at java.base/java.lang.System.loadLibrary(System.java:1902)
at org.jpl7.JPL.loadNativeLibrary(JPL.java:114)
at org.jpl7.fli.Prolog.<clinit>(Prolog.java:71)
at org.jpl7.Query.open(Query.java:369)
at org.jpl7.Term.textToTerm(Term.java:155)
at org.jpl7.Query.<init>(Query.java:169)
at Main.main(Main.java:7)
I have the swi prolog 64 bit.
I've tried uninstalling it and use the 32 bit but it did not work.
What I did so far:
I added SWI_HOME_DIR to my Environment Variables.
I also added the swi path to Path variable.
I added the jpl library to my project (and it added it successfully).
The code I was trying to run:
import org.jpl7.*;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Query q = new Query("true");
q.hasSolution();
Map<String,Term>[] res = q.allSolutions();
for (int i = 0; i < res.length; i++) {
System.out.println(res[i]);
}
}
}
So, is jpl.dll in any of the listed directories:
C:\Program Files\Java\jdk-12\bin ... probably not
C:\WINDOWS\Sun\Java\bin ... probably not
C:\WINDOWS\system32 ... probably not
C:\WINDOWS ... probably not
c:\swipl\bin ... apparently yes as c:\swipl\bin\jpl.dll exists?
${env_var:PATH} ... apparently not
Try the suggestion from this question in your Java program:
File nativeFile = new File(filename + ".dll");
if (!nativeFile.exists())
System.exit(1);
System.load(nativeFile);
Note that just having jpl.jar is not enough. One needs the jpl.dll file, too. jpl.jar is good for the Java part of the Java-Prolog bridge, but to be able to call a non-JVM compilate, we need to get into system-level details, Hence the dll file.
See troubleshooting tips here: JPL Deploying for users - on Windows
From the above page:
If the Java examples complain that
The dynamic link library libpl.dll could not be found in the specified path
or
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\paul\bin\jpl.dll: Can't find dependent libraries
then there is no SWI-Prolog library libpl.dll in any folder on your
PATH: you should have a PATH entry such as C:\Program Files\pl\bin.
The libpl.dll should contain the code for SWI-Prolog itself.

Ensuring files are available to the JVM

I'm trying to install TensorFlow for Java on Windows 10 using this Article
. I followed the steps carefully but the windows commands didn't work with me so I decided to do it manually.
The first command is to make the .jar part of the classpath and I did it manually
but the second step was to ensure that the following two files are available to the JVM: the .jar file and the extracted JNI library
but I don't know how to do that manually
The code:
package securityapplication;
import org.tensorflow.TensorFlow;
import org.tensorflow.Graph;
import org.tensorflow.Session;
import org.tensorflow.Tensor;
public class SecurityApplication {
public static void main(String[] args) throws Exception {
try (Graph g = new Graph()) {
final String value = "Hello from " + TensorFlow.version();
// Construct the computation graph with a single operation, a constant
// named "MyConst" with a value "value".
try (Tensor t = Tensor.create(value.getBytes("UTF-8"))) {
// The Java API doesn't yet include convenience functions for adding operations.
g.opBuilder("Const", "MyConst").setAttr("dtype", t.dataType()).setAttr("value", t).build();
}
// Execute the "MyConst" operation in a Session.
try (Session s = new Session(g);
Tensor output = s.runner().fetch("MyConst").run().get(0)) {
System.out.println(new String(output.bytesValue(), "UTF-8"));
}
}
}
}
could someone help? cuz my program that uses TensorFlow still have the following error
The text in the image is :
Exception in thread "main" java.lang.UnsatisfiedLinkError: Cannot find TensorFlow native library for OS: windows, architecture: x86. 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:66)
at org.tensorflow.NativeLibrary.load(NativeLibrary.java:66)
at org.tensorflow.TensorFlow.init(TensorFlow.java:36)
at org.tensorflow.TensorFlow.<clinit>(TensorFlow.java:40)
at org.tensorflow.Graph.<clinit>(Graph.java:194)
at securityapplication.SecurityApplication.main(SecurityApplication.java:15) Java Result: 1 BUILD SUCCESSFUL (total time: 4 seconds)
The result after running the first command in cmd:
The result after running the second command in Windows PowerShell:
Any suggestions?!
Thank you
The first command failure (javac) suggests that the javac command is not in your PATH environment variables. See for example, this StackOverflow question
For the second command failure, I believe the space after -D is what is causing you trouble as Holger suggested.
IDEs like Eclipse and others also provide a means to set the java.library.path property for the JVM (see this StackOverflow answer for example).
Background: TensorFlow for Java consists of a Java library (packaged in a .jar file) and a native library (.dll on Windows, distributed in a .zip file). You need to ensure that the .jar file is in the classpath and the directory containing the .dll is in included in the java.library.path of the JVM when executing a program.
Hope that helps.

Calling Fortran DLL in Netbeans IDE 8.0.2 Java

I have an issue. I got a DLL written in Fortran. And I want to call this DLL in Java.
Everything is working fine for other DLLs when I try to call them from a test-Java program. The DLL is existing. Unfortunately, regardless whether I use System.load and mention the whole path or use the loadLibrary method and mention only the DLL's name the same error message is returned:
java.lang.UnsatisfiedLinkError: C:\Windows\System32\MYDLL.dll: Not enough storage is available to process this command
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1929)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1847)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1119)
at OnlyForTesting.(OnlyForTesting.java:11)
Exception in thread "main" Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
Here is my code:
public class TryToCallDLL {
private native void method();
public static void main(String[] args){
System.out.println("Test\n");
new TryToCallDLL().method();
}
static{
System.load("C:\\Users\\xxx\\Documents\\NetBeansProjects\\JNItutorial\\src\\TryToCallDLL\\Debug\\MYDLL.dll");
}
}
I was searching for anything helpful related to similar errors but nothing was working. There was though one comment stating it could be related to a limited heap storage.
I want to emphasize that this DLL's purpose is calculating using a lot of data.
I also want to add that the DLL is a 32bit version. My PC is 64 bit, I have two Netbeans version (32bit and 64bit), but running the Java program with the 32bit version.
Any suggestions are welcomed. Thank you in advance!
EDIT:
I increased the heap in the settings: -Xmx1024m
The DLL itself has a size of 1,955 KB.
Still the DLL cannot be loaded.

Sqlite java.lang.UnsatisfiedLinkError in linux

I have a program that uses Sqlite database. It works fine on Windows (exported jar or directly in Eclipse) but when I move it to linux server (plan is to use run it at certain intervals, cron job). I'm exporting it to jar from Eclipse and packing the sqlite-jdbc4-3.8.2-SNAPSHOT.jar with it. Error is this:
/$ /usr/bin/java -jar /home/username/Software.jar /home/username/
java.lang.UnsatisfiedLinkError: /tmp/sqlite-3.8.2-amd64-libsqlitejdbc.so: /tmp/sqlite-3.8.2-amd64-libsqlitejdbc.so: failed to map segment from shared object: Operation not permitted
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.sqlite.core.NativeDB._open(Ljava/lang/String;I)V
at org.sqlite.core.NativeDB._open(Native Method)
at org.sqlite.core.DB.open(DB.java:161)
at org.sqlite.core.CoreConnection.open(CoreConnection.java:145)
at org.sqlite.core.CoreConnection.<init>(CoreConnection.java:66)
at org.sqlite.jdbc3.JDBC3Connection.<init>(JDBC3Connection.java:21)
at org.sqlite.jdbc4.JDBC4Connection.<init>(JDBC4Connection.java:23)
at org.sqlite.SQLiteConnection.<init>(SQLiteConnection.java:44)
at org.sqlite.JDBC.createConnection(JDBC.java:113)
at org.sqlite.JDBC.connect(JDBC.java:87)
at java.sql.DriverManager.getConnection(DriverManager.java:582)
at java.sql.DriverManager.getConnection(DriverManager.java:207)
....
So before you ask, I've made sure that sqlite-3.8.2-amd64-libsqlitejdbc.so in /tmp/ has all permissions (rwxrwxrwx). Still that native library is causing problems. It does get copied in /tmp/ folder though. That being said I totally suck in Linux... and for that reason I'm pretty much clueless what to try next.
What should I do? Switch connector?
EDIT:
Solved the problem by using System.setProperty("java.io.tmpdir", "/home/username/"); Apparently it for some reason couldn't execute the native library from tmp folder... Probably because it was created by root. Also I had to revert back to sqlite-jdbc-3.7.2.jar because the new one crashes on linux.
I had same problem, and I found the solution in this GitHub issue:
JAVA_OPTS=-Djava.io.tmpdir=/path/to/some/other/tmpdir bin/cerebro
Also look at this other SO answer.

Loading native libraries in java

I have an eclipse project with two classes. The class "SomeClass1" has a native method:
SomeClass1
public class SomeClass1 {
static {
System.loadLibrary("libname"); // Load the native library.
}
public native void some_method(); // implemented in the library
// .... other non methods ....
}
The other class "SomeClass2" uses the native method of "SomeClass1". Like:
SomeClass2
public class SomeClass2{
public static void main(String[] args) {
SomeClass1 s = new SomeClass1();
s.some_method();
}
// ....other methods....
}
However when it calls that method it throws an error like this:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no libname in java.library.path
....
at java.lang.System.loadLibrary(Unknown Source)
at x.x.x.SomeClass1.<clinit>(SomeClass1.java:128)
at SomeClass2.main(SomeClass2.java:10)
I think the error has something to do with java not knowing where to look for the native library.
Question1
When I use: -Djava.library.path="C:\Users.....\libfolder\" as run argument in eclipse and print the value of: System.getProperty("java.library.path"); I see alot of directories printed but not the directory that I specified in the argument. What am I doing wrong?
Question2
When I do: System.loadLibrary("name"); do I need to call the library "name.so" or "libname.so"?
Question3
If the library would be found but was a 64 bit library while the platform it is loaded on is 32 bit, would it also give a unsatisfiedLinkError or would a different error be given?
Question4
Can I specify the path to the library relative to the projects folder or relative to the file in which the library is loaded?
Hope you are able to answer (some of) my questions.
Grtz Stefan
Question 1:
You should not add this as a run argument, but as a VM argument. It's not an argument for your program, but for the JVM.
Question 2:
(Also #IanRoberts ) : The System.loadLibrary(name) call will automatically derive the name of the actual library from the given name. That means that it will append ".dll" on windows, and use "lib" + name + ".so" on linux. Otherwise, loading a native lib would not be possible in a platform-independent way!
Question 3:
In general, the UnsatsfiedLinkError is distressingly common. It's in fact true to say: The UnsatisfiedLinkError does not tell you more than "Something is wrong". You can only hope for the actual error message to be more descriptive, and this would (fortunately) be the case if you had a 32/64bit mismatch - at least on windows:
Trying to load a 32bit lib on a 64bit system will cause the message: "Can't load IA 32-bit .dll on a AMD 64-bit platform"
Trying to load a 64bit lib on a 32bit system will cause the message: "... is not a valid Win32 application"
(I'm not sure about the message for other operating systems, though, but your message indicates that the library is just not found, and not that there's a problem with the library itself)
(Question 4: I'm rather sure that this is possible, but not absolutely sure (and can't try it out) at the moment. In general, the library must be in a path that is visible via the PATH environment variable, or via the java.library.path. In doubt, it should always work then the native libs are in the same directory as where you are starting your program from)

Categories

Resources