JDK-8293659 : Improve UnsatisfiedLinkError error message to include dlopen error details
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang:class_loading
  • Affected Version: 18
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2022-09-12
  • Updated: 2023-10-17
  • Resolved: 2022-09-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 17 JDK 20
17.0.10-oracleFixed 20 b16Fixed
Related Reports
Relates :  
Description
When trying to load a  x64  lib on macOS aarch64 one got previously this  detailed message before JDK-8275703:

java.lang.UnsatisfiedLinkError: /testing/jco3/macOsx64/libsapjco3.dylib: dlopen(/testing/jco3/macOsx64/libsapjco3.dylib, 1): no suitable image found.  Did find:
                /testing/jco3/macOsx64/libsapjco3.dylib: mach-o, but wrong architecture
                /testing/jco3/macOsx64/libsapjco3.dylib: mach-o, but wrong architecture [in thread "main"]

After JDK-8275703, the error message does not include the details:
java.lang.UnsatisfiedLinkError: Can't load library: /testing/jco3/macOsx64/libsapjco3.dylib [in thread "main"] 

The error details are useful to help diagnosing user's error like mismatched target architecture.
Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/812 Date: 2022-10-20 09:44:42 +0000
20-10-2022

jdk17 backport request I would like to backport this patch to jdk17u-dev , because the predecessor JDK-8275703 has been backported too and the improved UnsatisfiedLinkError error message is helpful. The backport is low risk but not clean, needs a bit adjustment because the load-call in NativeLibraries.java is different in 17.
20-10-2022

Changeset: da4fdfbb Author: Matthias Baesken <mbaesken@openjdk.org> Date: 2022-09-21 11:32:24 +0000 URL: https://git.openjdk.org/jdk/commit/da4fdfbbf4ba72ddaf4f27d95f71e95b7ebf8cc1
21-09-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/10286 Date: 2022-09-15 11:54:41 +0000
15-09-2022

diff --git a/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java b/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java index c5ede021e00..07ec5920999 100644 --- a/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java +++ b/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java @@ -328,7 +328,20 @@ public final class NativeLibraries { throw new InternalError("Native library " + name + " has been loaded"); } - return load(this, name, isBuiltin, loadLibraryOnlyIfPresent); + return load(this, name, isBuiltin, throwExceptionIfFail()); + } + + private boolean throwExceptionIfFail() { + boolean fileExists = AccessController.doPrivileged(new PrivilegedAction<>() { + public Boolean run() { + File file = new File(name); + return file.exists(); + } + }); + + // If the file exists but fails to load, UnsatisfiedLinkException thrown by the VM + // will include the error message from dlopen to provide diagnostic information + return fileExists || loadLibraryOnlyIfPresent; }
14-09-2022

The file existence check on macOS is to handle dynamic linker cache. Before JDK-8275703, System::loadLibrary calls JVM_LoadLibrary only if the filepath exists. If any error in dlopen of the given path, System::loadLibrary will fail with UnsatisfiedLinkException. To support dynamic linker cache, dlopen may succeed with non-existent path if it's in the dynamic linker cache and hence JVM_LoadLibrary was changed to specify the `throwException` parameter if true, UnsatisfiedLinkException will be thrown by the VM. A possible fix for this would be if macOS supports dynamic linker cache, it calls JVM_LoadLibrary with throwException = false only if the file does not exist; throwException = true if the file exists.
12-09-2022