Repository navigation
NativeBinaryLoader.loadLibrary() fails silently if clean extraction fails #46
Description
Activity
There is an Exception class dedicated to this:
https://github.com/Electrostat-Lab/jSnapLoader/blob/master/snaploader%2Fsrc%2Fmain%2Fjava%2Felectrostatic4j%2Fsnaploader%2Fthrowable%2FUnSupportedSystemError.javaIt might be the case that the caller function misbehaves.
Perhaps a concrete example will clarify the issue.
I modified TestBasicFeatures.java to report whether
loadLibrary()throws an exception:+++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java @@ -74,7 +74,14 @@ loader.setRetryWithCleanExtraction(true); /* Native dynamic library properties */ printDetails(loader); - loader.loadLibrary(LoadingCriterion.INCREMENTAL_LOADING); \ No newline at end of file + + try { + loader.loadLibrary(LoadingCriterion.INCREMENTAL_LOADING); + } catch (Exception exception) { + System.err.println("loadLibrary threw an exception"); + System.exit(-1); + } + System.err.println("no exception thrown"); \ No newline at end of file } protected static void printDetails(NativeBinaryLoader loader) {
Then I replaced the
NativeDynamicLibraryfor my platform with an invalid entry:# This patch file was generated by NetBeans IDE # It uses platform neutral UTF-8 encoding and \n newlines. --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java @@ -58,7 +58,7 @@ public static final NativeDynamicLibrary[] libraries = new NativeDynamicLibrary[] { DefaultDynamicLibraries.LINUX_X86, - DefaultDynamicLibraries.LINUX_X86_64, + new NativeDynamicLibrary("nonexistent/directory", "junk", PlatformPredicate.LINUX_X86_64), new NativeDynamicLibrary("lib/windows/x86", "libjmealloc.dll", PlatformPredicate.WIN_X86), new NativeDynamicLibrary("lib/windows/x86-64", "libjmealloc.dll", PlatformPredicate.WIN_X86_64), DefaultDynamicLibraries.MAC_X86,
When I execute this modified
TestBasicFeatures, no exception is thrown.During the initialization stage; this function should throw an
UnSupportedSystemErrorprior to calling the loading command.jSnapLoader/snaploader/src/main/java/electrostatic4j/snaploader/NativeBinaryLoader.java
Lines 126 to 159 in b19346f
public NativeBinaryLoader initPlatformLibrary() throws UnSupportedSystemError { final boolean[] isSystemFound = new boolean[]{false}; // search for the compatible library using the predefined predicate // a predicate is a conditional statement composed of multiple propositions // representing the complete system variant (OS + ARCH + VM). registeredLibraries.forEach(nativeDynamicLibrary -> { if (isSystemFound[0]) { return; } // re-evaluate the library info part if (libraryInfo != null) { nativeDynamicLibrary.initWithLibraryInfo(libraryInfo); } if (nativeDynamicLibrary.getPlatformPredicate().evaluatePredicate()) { this.nativeDynamicLibrary = nativeDynamicLibrary; isSystemFound[0] = true; } }); // execute a system found listeners if (isSystemFound[0]) { if (systemDetectionListener != null) { systemDetectionListener.onSystemFound(this, nativeDynamicLibrary); } } else { if (systemDetectionListener != null) { systemDetectionListener.onSystemNotFound(this); } throw new UnSupportedSystemError(NativeVariant.OS_NAME.getProperty(), NativeVariant.OS_ARCH.getProperty()); } return this; } Please verify whether the output log has an
UnSupportedSystemError.That error was not thrown because
isSystemFound[0]wastruein line 146.The file locator system throws these, when a non-existent library is trying to be located:
> Task :snaploader-examples:run -------------------------------------------------------------- OS: Linux ARCH: amd64 VM: Java HotSpot(TM) 64-Bit Server VM -------------------------------------------------------------- Jar Path: /media/pavl-g/pavl-g/Digital-Library/Projects/jSnapLoader/snaploader-examples/libs/jme3-alloc-desktop-1.0.0-pre-gamma-2.jar Library Directory: nonexistent/directory Compressed library path: nonexistent/directory/junk Extracted library absolute path: /media/pavl-g/pavl-g/Digital-Library/Projects/jSnapLoader/snaploader-examples/libs/junk Is Extracted: false -------------------------------------------------------------- Oct 04, 2026 2:44:38 PM electrostatic4j.snaploader.library.LibraryExtractor initialize(int) INFO: File extractor initialized with hash key #1705710286 Oct 04, 2026 2:44:38 PM electrostatic4j.snaploader.library.LibraryLocator close INFO: File locator #1848380775 resources closed! Oct 04, 2026 2:44:38 PM electrostatic4j.snaploader.NativeBinaryLoader$2 preInitLibraryLocator SEVERE: Locating native libraries has failed! electrostatic4j.snaploader.throwable.FilesystemResourceInitializationException: Cannot locate the file entry in the compression! at electrostatic4j.snaploader.util.StreamObjectValidator.validateAndThrow(StreamObjectValidator.java:62) at electrostatic4j.snaploader.filesystem.FileLocator.externalCompressionRoutine(FileLocator.java:179) at electrostatic4j.snaploader.filesystem.FileLocator.initialize(FileLocator.java:131) at electrostatic4j.snaploader.NativeBinaryLoader.initializeLibraryExtractor(NativeBinaryLoader.java:457) at electrostatic4j.snaploader.NativeBinaryLoader.cleanExtractBinary(NativeBinaryLoader.java:379) at electrostatic4j.snaploader.NativeBinaryLoader.loadLibrary(NativeBinaryLoader.java:196) at electrostatic4j.snaploader.examples.TestBasicFeatures.main(TestBasicFeatures.java:78) Oct 04, 2026 2:44:38 PM electrostatic4j.snaploader.library.LibraryExtractor close INFO: File extractor #1705710286 resources closed! Oct 04, 2026 2:44:38 PM electrostatic4j.snaploader.NativeBinaryLoader cleanExtractBinary INFO: File extractor handler initialized! Oct 04, 2026 2:44:38 PM electrostatic4j.snaploader.NativeBinaryLoader$1 cleanExtractBinary SEVERE: Extraction has failed! electrostatic4j.snaploader.throwable.FilesystemResourceInitializationException: Broken file locator stream provider! at electrostatic4j.snaploader.util.StreamObjectValidator.validateAndThrow(StreamObjectValidator.java:62) at electrostatic4j.snaploader.filesystem.FileExtractor.extract(FileExtractor.java:138) at electrostatic4j.snaploader.filesystem.ConcurrentFileExtractor.extract(ConcurrentFileExtractor.java:72) at electrostatic4j.snaploader.NativeBinaryLoader.cleanExtractBinary(NativeBinaryLoader.java:435) at electrostatic4j.snaploader.NativeBinaryLoader.loadLibrary(NativeBinaryLoader.java:196) at electrostatic4j.snaploader.examples.TestBasicFeatures.main(TestBasicFeatures.java:78) BUILD SUCCESSFUL in 2s 4 actionable tasks: 1 executed, 3 up-to-dateDo you recognize these at your runtime logs?
However, if a broken file already exists; an
UnSatisfiedLinkErroris thrown because the file is too short (i.e., Corrupted file):java.lang.UnsatisfiedLinkError: /media/pavl-g/pavl-g/Digital-Library/Projects/jSnapLoader/snaploader-examples/libs/junk: /media/pavl-g/pavl-g/Digital-Library/Projects/jSnapLoader/snaploader-examples/libs/junk: file too short at java.base/jdk.internal.loader.NativeLibraries.load(Native Method) at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:331) at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:197) at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:139) at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2404) at java.base/java.lang.Runtime.load0(Runtime.java:817) at java.base/java.lang.System.load(System.java:2015) at electrostatic4j.snaploader.NativeBinaryLoader.loadBinary(NativeBinaryLoader.java:339) at electrostatic4j.snaploader.NativeBinaryLoader.loadLibrary(NativeBinaryLoader.java:192) at electrostatic4j.snaploader.examples.TestBasicFeatures.main(TestBasicFeatures.java:78)Here's the complete output of "TestBasicFeatures.java" running on Linux with the changes described above:
------------------------------------------------------------- OS: Linux ARCH: amd64 VM: OpenJDK 64-Bit Server VM -------------------------------------------------------------- Jar Path: /mnt/virginia/home/sgold/NetBeansProjects/ext/jSnapLoader/snaploader-examples/libs/jme3-alloc-desktop-1.0.0-pre-gamma-2.jar Library Directory: nonexistent/directory Compressed library path: nonexistent/directory/junk Extracted library absolute path: /mnt/virginia/home/sgold/NetBeansProjects/ext/jSnapLoader/snaploader-examples/libs/junk Is Extracted: true -------------------------------------------------------------- OpenJDK 64-Bit Server VM warning: You have loaded library /mnt/virginia/home/sgold/NetBeansProjects/ext/jSnapLoader/snaploader-examples/libs/junk which might have disabled stack guard. The VM will try to fix the stack guard now. It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'. Oct 04, 2026 10:22:36 AM electrostatic4j.snaploader.NativeBinaryLoader loadBinary SEVERE: Cannot load the dynamic library: /mnt/virginia/home/sgold/NetBeansProjects/ext/jSnapLoader/snaploader-examples/libs/junk java.lang.UnsatisfiedLinkError: /mnt/virginia/home/sgold/NetBeansProjects/ext/jSnapLoader/snaploader-examples/libs/junk: /mnt/virginia/home/sgold/NetBeansProjects/ext/jSnapLoader/snaploader-examples/libs/junk: file too short at java.base/jdk.internal.loader.NativeLibraries.load(Native Method) at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:388) at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:232) at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:174) at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2394) at java.base/java.lang.Runtime.load0(Runtime.java:755) at java.base/java.lang.System.load(System.java:1970) at electrostatic4j.snaploader.NativeBinaryLoader.loadBinary(NativeBinaryLoader.java:339) at electrostatic4j.snaploader.NativeBinaryLoader.loadLibrary(NativeBinaryLoader.java:192) at electrostatic4j.snaploader.examples.TestBasicFeatures.main(TestBasicFeatures.java:79) Oct 04, 2026 10:22:36 AM electrostatic4j.snaploader.library.LibraryExtractor initialize(int) INFO: File extractor initialized with hash key #214123406 Oct 04, 2026 10:22:36 AM electrostatic4j.snaploader.library.LibraryLocator close INFO: File locator #1848380775 resources closed! Oct 04, 2026 10:22:36 AM electrostatic4j.snaploader.NativeBinaryLoader$2 preInitLibraryLocator SEVERE: Locating native libraries has failed! electrostatic4j.snaploader.throwable.FilesystemResourceInitializationException: Cannot locate the file entry in the compression! at electrostatic4j.snaploader.util.StreamObjectValidator.validateAndThrow(StreamObjectValidator.java:62) at electrostatic4j.snaploader.filesystem.FileLocator.externalCompressionRoutine(FileLocator.java:179) at electrostatic4j.snaploader.filesystem.FileLocator.initialize(FileLocator.java:131) at electrostatic4j.snaploader.NativeBinaryLoader.initializeLibraryExtractor(NativeBinaryLoader.java:457) at electrostatic4j.snaploader.NativeBinaryLoader.cleanExtractBinary(NativeBinaryLoader.java:379) at electrostatic4j.snaploader.NativeBinaryLoader.loadBinary(NativeBinaryLoader.java:366) at electrostatic4j.snaploader.NativeBinaryLoader.loadLibrary(NativeBinaryLoader.java:192) at electrostatic4j.snaploader.examples.TestBasicFeatures.main(TestBasicFeatures.java:79) Oct 04, 2026 10:22:36 AM electrostatic4j.snaploader.library.LibraryExtractor close INFO: File extractor #214123406 resources closed! Oct 04, 2026 10:22:36 AM electrostatic4j.snaploader.NativeBinaryLoader cleanExtractBinary INFO: File extractor handler initialized! Oct 04, 2026 10:22:36 AM electrostatic4j.snaploader.NativeBinaryLoader$1 cleanExtractBinary SEVERE: Extraction has failed! electrostatic4j.snaploader.throwable.FilesystemResourceInitializationException: Broken file locator stream provider! at electrostatic4j.snaploader.util.StreamObjectValidator.validateAndThrow(StreamObjectValidator.java:62) at electrostatic4j.snaploader.filesystem.FileExtractor.extract(FileExtractor.java:138) at electrostatic4j.snaploader.filesystem.ConcurrentFileExtractor.extract(ConcurrentFileExtractor.java:72) at electrostatic4j.snaploader.NativeBinaryLoader.cleanExtractBinary(NativeBinaryLoader.java:435) at electrostatic4j.snaploader.NativeBinaryLoader.loadBinary(NativeBinaryLoader.java:366) at electrostatic4j.snaploader.NativeBinaryLoader.loadLibrary(NativeBinaryLoader.java:192) at electrostatic4j.snaploader.examples.TestBasicFeatures.main(TestBasicFeatures.java:79) no exception thrown
How is the application supposed to detect that extraction has failed?
Reacted by Pavly Gerges (pavl_g)How is the application supposed to detect that extraction has failed?
I've just found the problem and its solution; the problem is that the Java Legacy
FileOutputStreamcreates anew Filewhen it's initialized regardless of whether a physical file pre-existed, which in our case leads to a creation of blank file that is too short or corrupt to be loadable by the dynamic loader.... The result cannot be avoided by jSnapLoader, so the solution is to delete that blank file when the library locator has failed...The
UnSatisfiedLinkErrorthrown in this case is not as result of trying to invoke a native function, but rather as a result of trying to load a bad file that is not a native binary.I will submit a PR and let's continue discussion there.
- linked a pull request that will close this issueFix UnSatisfiedLinkError when trying to load non-existent libraries #47
on Oct 4, 2026
If none of the registered native libraries is loadable (for instance because the libraries with matching predicates are missing from the JAR) the code above does not throw an exception. The failure isn't discovered until the application tries to invoke a native method, at which time a
UnsatisfiedLinkErroris thrown.I expected an exception to be thrown during
loadLibrary(). Ideally diagnostics should indicate:and