Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
4 changes: 4 additions & 0 deletions snaploader-examples/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ tasks.register("TestMultiThreading") {
application.mainClass = 'electrostatic4j.snaploader.examples.TestMultiThreading'
}

tasks.register("TestRetryExhaustionException") {
application.mainClass = 'electrostatic4j.snaploader.examples.TestRetryExhaustionException'
}

task copyLibs(type: Copy) {
from (libsDir) {
include '**/*.jar'
Expand Down
Binary file added snaploader-examples/libs/corrupted-lib.jar
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2023-2025, The Electrostatic-Sandbox Distributed Simulation Framework, jSnapLoader
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'Electrostatic-Sandbox' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package electrostatic4j.snaploader.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import electrostatic4j.snaploader.LibraryInfo;
import electrostatic4j.snaploader.LoadingCriterion;
import electrostatic4j.snaploader.NativeBinaryLoader;
import electrostatic4j.snaploader.filesystem.DirectoryPath;
import electrostatic4j.snaploader.platform.NativeDynamicLibrary;
import electrostatic4j.snaploader.platform.util.DefaultDynamicLibraries;
import electrostatic4j.snaploader.platform.util.NativeVariant;
import electrostatic4j.snaploader.platform.util.PlatformPredicate;
import electrostatic4j.snaploader.platform.util.PropertiesProvider;

/**
* Tests retry exhaustion on a broken library.
*
* @author pavl_g.
*/
public class TestRetryExhaustionException {
public static void main(String[] args) throws Exception {

final Path compressionPath = Paths.get(PropertiesProvider.USER_DIR.getSystemProperty(), "libs", "corrupted-lib.jar");
final Path extractionPath = Files.createDirectories(Paths.get(PropertiesProvider.USER_DIR.getSystemProperty(), "libs",
NativeVariant.OS_NAME.getProperty(), NativeVariant.OS_ARCH.getProperty()));

final LibraryInfo libraryInfo = new LibraryInfo(new DirectoryPath(compressionPath.toString()), new DirectoryPath("lib/placeholder"),
"jmealloc", new DirectoryPath(extractionPath.toString()));

final NativeDynamicLibrary[] libraries = new NativeDynamicLibrary[] {
DefaultDynamicLibraries.LINUX_X86_64,
DefaultDynamicLibraries.LINUX_X86,
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,
DefaultDynamicLibraries.MAC_X86_64,
};

final NativeBinaryLoader loader = new NativeBinaryLoader(libraryInfo);

loader.registerNativeLibraries(libraries).initPlatformLibrary();
loader.setLoggingEnabled(true);
loader.setRetryWithCleanExtraction(true);
/* Native dynamic library properties */
printDetails(loader);
loader.loadLibrary(LoadingCriterion.INCREMENTAL_LOADING);
}

public static void printDetails(NativeBinaryLoader loader) {
System.out.println("--------------------------------------------------------------");
System.out.println("OS: " + NativeVariant.OS_NAME.getProperty());
System.out.println("ARCH: " + NativeVariant.OS_ARCH.getProperty());
System.out.println("VM: " + NativeVariant.JVM.getProperty());
System.out.println("--------------------------------------------------------------");
System.out.println("Jar Path: " + loader.getNativeDynamicLibrary().getJarPath());
System.out.println("Library Directory: " + loader.getNativeDynamicLibrary().getPlatformDirectory());
System.out.println("Compressed library path: " + loader.getNativeDynamicLibrary().getCompressedLibrary());
System.out.println("Extracted library absolute path: " + loader.getNativeDynamicLibrary().getExtractedLibrary());
System.out.println("Is Extracted: " + loader.getNativeDynamicLibrary().isExtracted());
System.out.println("--------------------------------------------------------------");
}
}
4 changes: 2 additions & 2 deletions snaploader/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ plugins {
}

tasks.register("generateJavadocJar", Jar) {
classifier = 'javadoc'
archiveClassifier.set("javadoc")
from javadoc
}

tasks.register("generateSourcesJar", Jar) {
classifier = 'sources'
archiveClassifier.set("sources")
from sourceSets.main.allSource
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023-2024, The Electrostatic-Sandbox Distributed Simulation Framework, jSnapLoader
* Copyright (c) 2023-2025, The Electrostatic-Sandbox Distributed Simulation Framework, jSnapLoader
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -46,6 +46,7 @@
import electrostatic4j.snaploader.library.LibraryLocator;
import electrostatic4j.snaploader.platform.NativeDynamicLibrary;
import electrostatic4j.snaploader.platform.util.NativeVariant;
import electrostatic4j.snaploader.throwable.LoadingRetryExhaustionException;
import electrostatic4j.snaploader.throwable.UnSupportedSystemError;
import electrostatic4j.snaploader.util.SnapLoaderLogger;

Expand Down Expand Up @@ -84,6 +85,10 @@ public class NativeBinaryLoader {
*/
protected boolean retryWithCleanExtraction;

protected int maxNumberOfLoadingFailure = 2;

protected int numberOfLoadingFailure = 0;

/**
* Instantiates a native dynamic library loader to extract and load a system-specific native dynamic library.
*/
Expand Down Expand Up @@ -234,12 +239,18 @@ public FileLocalizingListener getLibraryLocalizingListener() {
return libraryLocalizingListener;
}

public void setMaxNumberOfLoadingFailure(int maxNumberOfLoadingFailure) {
this.maxNumberOfLoadingFailure = Math.abs(maxNumberOfLoadingFailure);
}

/**
* Loads a native binary using the platform-dependent object, for Android;
* the library is loaded by its basename (variant is managed internally by the android sdk).
*
* @param library the platform-specific library to load
* @throws IOException in case the binary to be extracted is not found on the specified jar
* @throws LoadingRetryExhaustionException if the number of loading failure exceeds the specified
* number.
*/
protected void loadBinary(NativeDynamicLibrary library) throws Exception {
try {
Expand All @@ -264,10 +275,17 @@ protected void loadBinary(NativeDynamicLibrary library) throws Exception {
}
/* Retry with clean extract */
if (isRetryWithCleanExtraction()) {
cleanExtractBinary(library);
if (nativeBinaryLoadingListener != null) {
nativeBinaryLoadingListener.onRetryCriterionExecution(this);
}
// limit the number of retries to maxNumberOfLoadingFailure
if (numberOfLoadingFailure >= maxNumberOfLoadingFailure) {
numberOfLoadingFailure = 0; /* reset the number to zero trials */
throw new LoadingRetryExhaustionException("Library loading retries exceeded the maximum!");
}
++numberOfLoadingFailure;
// Jump call -> Possible Recursive Call
cleanExtractBinary(library);
}
}
}
Expand All @@ -281,7 +299,7 @@ protected void loadBinary(NativeDynamicLibrary library) throws Exception {
*/
protected void cleanExtractBinary(NativeDynamicLibrary library) throws Exception {
libraryExtractor = initializeLibraryExtractor(library);
SnapLoaderLogger.log(Level.INFO, getClass().getName(), "cleanExtractBinary",
SnapLoaderLogger.log(Level.INFO, getClass().getName(), "cleanExtractBinary",
"File extractor handler initialized!");
/* CLEAR RESOURCES AND RESET OBJECTS ON-EXTRACTION */
libraryExtractor.setExtractionListener(new FileExtractionListener() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2023-2025, The Electrostatic-Sandbox Distributed Simulation Framework, jSnapLoader
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'Electrostatic-Sandbox' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package electrostatic4j.snaploader.throwable;

/**
* Thrown to indicate that loading retries have reached their maximum.
*
* @author pavl_g.
*/
public class LoadingRetryExhaustionException extends RuntimeException {
public LoadingRetryExhaustionException() {
}

public LoadingRetryExhaustionException(String message) {
super(message);
}

public LoadingRetryExhaustionException(String message, Throwable cause) {
super(message, cause);
}

public LoadingRetryExhaustionException(Throwable cause) {
super(cause);
}

public LoadingRetryExhaustionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}