How to load a JNI .dylib file with a dependency without getting an UnsatifiedLinkError?
macOS ld
builds a library dependency's path into the binary. The loader loading libSwiftHelloWorld.dylib
will only find libSwiftCode.dylib
if the latter is in the current directory. Loading the dependency in Java doesn't work because for the loader it's a different library.
You can change the built-in path for libSwiftCode.dylib
with the -install_name
argument (i.e. swiftc ... -Xlinker -install_name -Xlinker <your path>
). If you rebuild libSwiftHelloWorld.dylib
afterwards it will reference the path that you gave.
Getting an UnsatisfiedLinkError (undefined symbol) in Java while loading JNI dependencies even after successfully loading the required object file
I'm apologize that the java artifact may be broken currently...
you can use c++filt to demangle the symbol ;)
c++filt _ZN6google14FlagRegistererC1IbEEPKcS3_S3_PT_S5_
google::FlagRegisterer::FlagRegisterer<bool>(char const*, char const*, char const*, bool*, bool*)
In fact gflag has recently change its namespace from google::
to gflags::
and glog or protobobuf? try to find the correct one and I guess it failed...
note: Still not completely sure whose is the bad guy who use the google::
namespace since libortools merge all its static dependencies but I guess now you understand the bug...
note2: I have a patch in mizux/shared branch https://github.com/google/or-tools/commit/805bc0600f4b5645114da704a0eb04a0b1058e28#diff-e8590fe6fb5044985c8bf8c9e73c0d88R114
warning: this branch is currently broken and not ready yet. I'm trying ,for unix, to move from static to dynamic dependencies, so I need to fix all rpath, transitives deps etc... and in the process I also had to fix this issue (that I didn't reproduced while using static dependencies)
If too long to finish (we should create a release 6.7.2 or 6.8 (i.e. new artifact) by the end of May 2018) which maybe only contains this fix and not my branch...
Why do I recieve error 'java.lang.UnsatisfiedLinkError: Can't load library' when the file can be found?
Your computer very likely has a CPU with the ARM architecture, such as the M1 chip, instead of the x86 architecture.
Therefore, the JVM process cannot load the imgui-java64.dylib shared library because imgui-java currently only ships x86 CPU architecture shared libraries, not ARM ones.
See this GitHub issue: https://github.com/SpaiR/imgui-java/issues/123
and this (currently open) GitHub Pull Request: https://github.com/SpaiR/imgui-java/pull/112 to add ARM CPU support for imgui-java.
Your only solution is to probably incorporate the work currently having been done in that GitHub Pull Request and compile imgui-java locally yourself for your ARM CPU or wait until the PR is merged and a release of imgui-java ships with macOS ARM shared libraries.
java.lang.UnsatisfiedLinkError no *****.dll in java.library.path
In order for System.loadLibrary()
to work, the library (on Windows, a DLL) must be in a directory somewhere on your PATH
or on a path listed in the java.library.path
system property (so you can launch Java like java -Djava.library.path=/path/to/dir
).
Additionally, for loadLibrary()
, you specify the base name of the library, without the .dll
at the end. So, for /path/to/something.dll
, you would just use System.loadLibrary("something")
.
You also need to look at the exact UnsatisfiedLinkError
that you are getting. If it says something like:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
then it can't find the foo library (foo.dll) in your PATH
or java.library.path
. If it says something like:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
then something is wrong with the library itself in the sense that Java is not able to map a native Java function in your application to its actual native counterpart.
To start with, I would put some logging around your System.loadLibrary()
call to see if that executes properly. If it throws an exception or is not in a code path that is actually executed, then you will always get the latter type of UnsatisfiedLinkError
explained above.
As a sidenote, most people put their loadLibrary()
calls into a static initializer block in the class with the native methods, to ensure that it is always executed exactly once:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}
How to create .dylib from existing c project (concorde) for JNI
After a discussion in the comments with @P.N.N the solution was found.
The correct compilation command is:
gcc -g -O3 -arch x86_64 -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -L"../UTIL" -I"../INCLUDE" -I"../" -dynamiclib -o libtsp.dylib jconcorde_TSP.c ../UTIL/util.a kdtree.a
Compared to the original command the solution was to add a library path adding -L"../UTIL"
to the compilation and then add a missing static library to the command kdtree.a
Related Topics
How to Find Gcd, Lcm on a Set of Numbers
Aes/Cbc/Pkcs5Padding Encrypt in Java Decrypt in Ruby
Aes/Cbc Encrypt in Java, Decrypt in Ruby
How to Convert Between Iso-8859-1 and Utf-8 in Java
Spark Error - Unsupported Class File Major Version
Python: How to Execute a Jar File Through a Python Script
Translating Ruby Encryption Code to Java
How to Load a Jni .Dylib File with a Dependency Without Getting an Unsatifiedlinkerror
Why Would One Declare an Immutable Class Final in Java
How to Use Mockito with Junit5
Reading a Jsp Variable from JavaScript
Converting a Java Arraylist of Strings to a JavaScript Array
Why Does a Try/Catch Block Create New Variable Scope
Java Hotspot(Tm) 64-Bit Server Vm Warning: Ignoring Option Maxpermsize