kohlschutter / junixsocket

Unix Domain Sockets in Java 7 and newer (AF_UNIX), AF_TIPC, AF_VSOCK, and more
Apache License 2.0
433 stars 114 forks source link

`UnsatisfiedLinkError` in native GraalVM image #159

Open knutwannheden opened 1 month ago

knutwannheden commented 1 month ago

Describe the bug We are building a GraalVM native image and at runtime we are getting the following exception when calling AFUNIXSocketAddress#of(Path). Before adding too many possibly irrelevant details, I include the stack trace with all the listed suppressed exceptions, as I found a few related issues, where this information was requested.

java.lang.UnsatisfiedLinkError: Could not load native library junixsocket-native for architecture [aarch64-MacOSX]
    at org.newsclub.net.unix.NativeLibraryLoader.initCantLoadLibraryError(NativeLibraryLoader.java:377)
    at org.newsclub.net.unix.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:359)
    at org.newsclub.net.unix.NativeUnixSocket.<clinit>(NativeUnixSocket.java:92)
    at org.newsclub.net.unix.AFSocketAddress.<clinit>(AFSocketAddress.java:67)
    at java.base@17.0.9/java.lang.Class.ensureInitialized(DynamicHub.java:579)
    ...
    Suppressed: java.lang.Exception: No library specified with -Dorg.newsclub.net.unix.library.override=
        at org.newsclub.net.unix.NativeLibraryLoader.loadLibraryOverride(NativeLibraryLoader.java:286)
        at org.newsclub.net.unix.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:335)
        ... 21 more
    Suppressed: java.lang.ClassNotFoundException: org.newsclub.lib.junixsocket.custom.NarMetadata. This exception was synthesized during native image building from a call to java.lang.Class.forName(String) with constant arguments.
        at org.newsclub.net.unix.NativeLibraryLoader.tryProviderClass(NativeLibraryLoader.java:73)
        at org.newsclub.net.unix.NativeLibraryLoader.initLibraryCandidates(NativeLibraryLoader.java:398)
        at org.newsclub.net.unix.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:341)
        ... 21 more
    Suppressed: java.lang.UnsatisfiedLinkError: no junixsocket-native-2.10.0 in java.library.path
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibraryRelative(NativeLibrarySupport.java:136)
        at java.base@17.0.9/java.lang.ClassLoader.loadLibrary(ClassLoader.java:50)
        at java.base@17.0.9/java.lang.Runtime.loadLibrary0(Runtime.java:818)
        at java.base@17.0.9/java.lang.System.loadLibrary(System.java:1989)
        at org.newsclub.net.unix.NativeLibraryLoader$StandardLibraryCandidate.load(NativeLibraryLoader.java:141)
        at org.newsclub.net.unix.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:346)
        ... 21 more
    Suppressed: java.lang.UnsatisfiedLinkError: no junixsocket-native in java.library.path
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibraryRelative(NativeLibrarySupport.java:136)
        at java.base@17.0.9/java.lang.ClassLoader.loadLibrary(ClassLoader.java:50)
        at java.base@17.0.9/java.lang.Runtime.loadLibrary0(Runtime.java:818)
        at java.base@17.0.9/java.lang.System.loadLibrary(System.java:1989)
        at org.newsclub.net.unix.NativeLibraryLoader$StandardLibraryCandidate.load(NativeLibraryLoader.java:141)
        at org.newsclub.net.unix.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:346)
        ... 21 more

FWIW, I used to strings tool to make sure that the native libraries are actually contained in the GraalVM native image and I found these .dylib entries:

lib/x86_64-MacOSX-clang/jni/libjunixsocket-native-2.10.0.dylib
lib/aarch64-MacOSX-clang/jni/libjunixsocket-native-2.10.0.dylib

To Reproduce As GraalVM builds generally appear to be supported, it looks like this issue must be something specific to our build setup. But possibly the information provided is already enough to track this down.

Expected behavior Successful loading from GraalVM native image.

Output/Screenshots See above.

When running the application in non-native mode everything works as expected.

kohlschuetter commented 1 month ago

Thanks for reporting!

This looks like a very early failure of loading the native shared library, which is very unexpected.

Which GraalVM version do you use to build the native-image? Can you provide a description how you build it? (see junixsocket-selftest-native-image/pom.xml for an example how to build it with Maven)

What happens when you launch your program with

-Dorg.newsclub.net.unix.library.override.force=/absolute/path/to/aarch64-MacOSX-clang/jni/libjunixsocket-native-2.10.0.dylib

(copy the dylib to a regular directory in the file system first, and make sure to specify an absolute path)

knutwannheden commented 1 month ago

We are using GraalVM version 17 to build our application. The build is Gradle based and we have set a lot of different options, but I will try to gather them.

I didn't yet try using that override property, but what I did try and found to be working is if I place the dylib file next to the executable, then it all works.

kohlschuetter commented 2 weeks ago

@knutwannheden This could be due to a GraalVM issue with resource: URLs. Please definitely re-try with the latest GraalVM and report back. Thanks!

knutwannheden commented 2 weeks ago

Thanks for the update. I will definitely try that out then.

kohlschuetter commented 1 week ago

@knutwannheden I have tried to reproduce your bug with graalvm-jdk-17.0.9+11.1 (on macOS aarch64) but couldn't. It would be very helpful if you share your setup.