package fdb;
import com.apple.foundationdb.Database;
import com.apple.foundationdb.FDB;
import com.apple.foundationdb.tuple.Tuple;
public class Example {
public static void main(String[] args) {
try {
FDB fdb = FDB.selectAPIVersion(620);
try (Database db = fdb.open()) {
// Run an operation on the database
db.run(tr -> {
tr.set(Tuple.from("hello").pack(), Tuple.from("world").pack());
return null;
});
// Get the value of 'hello' from the database
String hello = db.run(tr -> {
byte[] result = tr.get(Tuple.from("hello").pack()).join();
return Tuple.fromBytes(result).getString(0);
});
System.out.println("Hello " + hello);
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
But I have exception:
java.lang.UnsatisfiedLinkError: C:\Users\art17em\AppData\Local\Temp\fdbjni3285163144695489469.library: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at com.apple.foundationdb.JNIUtil.loadLibrary(JNIUtil.java:106)
at com.apple.foundationdb.FDB.<clinit>(FDB.java:99)
at fdb.Example.main(Example.java:11)
Also I tried 2 different jdks: 1.8.0_181 and 11.0.7 but there is no any difference
I tried to debug-trace through the calling code and found that com.apple.foundationdb.JNIUtil#loadLibrary successfully copied the bundled /lib/windows/amd64/fdb_java.dll file in a temp location(C:\Users\art17em\AppData\Local\Temp\fdbjni3285163144695489469.library) and eventually calling System.load(filename); but the System.load() is failing with above exception.
Also I found strange code at com.apple.foundationdb.FDB
try {
JNIUtil.loadLibrary("fdb_c");
} catch (Throwable t) {
// EAT: this can be useful for loading on windows
}
JNIUtil.loadLibrary("fdb_java");
and noticed that loading of fdb_c library also failed for windows.
I’m not very familiar with debugging shared libraries on windows, but this stack overflow thread has some good suggestions and explanations of JNI search paths on Windows:
We would like to get to a root cause so that this is smoother in the future.
Thanks for your reply. I checked you link. It could helpful but I don’t know which dlls and search paths to these dlls I should fix.
Also today I got a little bit different stacktrace:
java.lang.UnsatisfiedLinkError: C:\Users\art17em\AppData\Local\Temp\fdbjni12487464082760794312.library:
The specified procedure could not be found
at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)
at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2498)
at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2694)
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2627)
at java.base/java.lang.Runtime.load0(Runtime.java:768)
at java.base/java.lang.System.load(System.java:1834)
at com.apple.foundationdb.JNIUtil.loadLibrary(JNIUtil.java:106)
at com.apple.foundationdb.FDB.<clinit>(FDB.java:99)
at fdb.Example.main(Example.java:11)
The message “The specified procedure could not be found” for UnsatisfiedLinkError indicates that a function in the root dll or in a dependent dll could not be found. The most likely cause of this in a JNI situation is that the native JNI function is not exported correctly. But this can apparently happen if a dependent DLL is loaded and that DLL is missing a function required by its parent.
By way of example, we have a library named input.dll. The DLL search order is to always look in the application directory first and the PATH directories last. In the past, we always ran executables from the same directory as input.dll. However, there is another input.dll in the windows system directory (which is in the middle of the DLL search order). So when running this from a java applet, if I include the code described above in the applet, which causes input.dll to be loaded, it loads the input.dll from the system directory. Because our code is expecting certain functions in input.dll which aren’t there (because it’s a different DLL) the load fails with an error message about missing procedures. Not because the JNI functions are exported wrong, but because the wrong dependent DLL was loaded and it didn’t have the expected functions in it.
Maybe I faced with the same problem - name conflict with dll files. On my computer fdb_java.dll could load not expected dependent dll with the same name. But I don’t how to check my suggestion and fix it
It looks like there’s an old tool from Microsoft called “Dependency Walker” (depends.exe) that can tell you which files + symbols fdb_java.dll recursively depends on, along with a list of unresolved symbols. It has apparently fallen out of maintenance, though there’s an open source reimplementation of it here with some additional functionality:
I haven’t used any of these tools, so I can’t really recommend one over the other, but they claim to be able to help debug this sort of issue. (Also, it wouldn’t surprise me if Microsoft rolled this functionality into some other development tool.)
On windows platform.
You can find fdb_c.dll in the installation directory of FundationDb, such as “C:\ProgramFiles\foundationdb\bin”. Load the fdb_c.dll in you application, you can run it.