How to Load a Jni .Dylib File with a Dependency Without Getting an Unsatifiedlinkerror

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



Leave a reply



Submit