From 2a754d735abaed74e7fac7e49f1a3d0a0b6647c9 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 06:54:38 -0400 Subject: [PATCH 01/27] FileExtractor#initialize(int): log memory initialization for external routines of file streams --- .../snaploader/filesystem/FileExtractor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileExtractor.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileExtractor.java index c6bd6cc..56d9c18 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileExtractor.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileExtractor.java @@ -34,7 +34,6 @@ import electrostatic4j.snaploader.throwable.FilesystemResourceInitializationException; import electrostatic4j.snaploader.util.SnapLoaderLogger; - import java.io.*; import java.util.logging.Level; @@ -72,9 +71,8 @@ public class FileExtractor implements OutputStreamProvider { * * @param fileLocator locates a filesystem inside a zip compression * @param destination an absolute filesystem path representing the extraction destination filesystem - * @throws FileNotFoundException if the destination filesystem path is not found */ - public FileExtractor(FileLocator fileLocator, String destination) throws FileNotFoundException { + public FileExtractor(FileLocator fileLocator, String destination) { this.fileLocator = fileLocator; this.destination = destination; } @@ -90,6 +88,8 @@ public void initialize(int size) throws Exception { // 1) sanity-check for double initializing // 2) sanity-check for pre-initialization using other routines if (this.fileOutputStream != null) { + SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", + "File extractor already initialized using external routines with hash key #" + getHashKey()); return; } try { From 38f5f0449b9b07ba2d7ae95305162724267f2984 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 06:56:10 -0400 Subject: [PATCH 02/27] FileLocator#initialize(int): log memory initialization for external routines (e.g., classpath routines) --- .../java/electrostatic4j/snaploader/filesystem/FileLocator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java index add139e..a6906b4 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java @@ -97,6 +97,8 @@ public void initialize(int size) throws IOException { // 2) sanity-check for pre-initialization using other routines // (e.g., classpath resources stream). if (this.fileInputStream != null) { + SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", + "File locator already initialized using external routines with hash key #" + getHashKey()); return; } try { From 4aa961259e5e492e45b41c799be024f90331966c Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 06:57:17 -0400 Subject: [PATCH 03/27] DirectoryPath: introduced directory path as a wrapper API for the file paths --- .../snaploader/filesystem/DirectoryPath.java | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 snaploader/src/main/java/electrostatic4j/snaploader/filesystem/DirectoryPath.java diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/DirectoryPath.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/DirectoryPath.java new file mode 100644 index 0000000..f63c167 --- /dev/null +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/DirectoryPath.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023-2024, 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.filesystem; + +import electrostatic4j.snaploader.platform.util.PropertiesProvider; + +/** + * A class denotes and provides a directory absolute path. + * + * @author pavl_g + */ +public final class DirectoryPath { + + /** + * An alias object for the current working directory absolute path. + */ + public static final DirectoryPath USER_DIR = + new DirectoryPath(PropertiesProvider.USER_DIR.getSystemProperty()); + + /** + * An alias object for the root user home directory absolute path. + */ + public static final DirectoryPath USER_HOME = + new DirectoryPath(PropertiesProvider.USER_DIR.getSystemProperty()); + + private String path; + + /** + * Instantiates a directory path from a string path (not null). + * + * @param path the directory path + */ + public DirectoryPath(final String path) { + this.path = path; + } + + /** + * Instantiates a directory path from a string path (not null) using + * the platform-specific file separators. + * + * @param root the root directory path + * @param entries the filesystem entries after the root path + */ + public DirectoryPath(final String root, final String... entries) { + this(root); + for (String entry: entries) { + if (entry == null) { + continue; + } + path = getPath() + PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + entry; + } + } + + /** + * Retrieves the absolute path to the specified directory path. + * + * @return a path in strings. + */ + public String getPath() { + return path; + } +} From 28554a1b7785bfe5ede87d0aaf3899ca505ac929 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 06:58:13 -0400 Subject: [PATCH 04/27] ConcurrentFileExtractor: removed unused imports and throws statements --- .../snaploader/filesystem/ConcurrentFileExtractor.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ConcurrentFileExtractor.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ConcurrentFileExtractor.java index 0d193e6..522e979 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ConcurrentFileExtractor.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ConcurrentFileExtractor.java @@ -32,7 +32,6 @@ package electrostatic4j.snaploader.filesystem; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.concurrent.locks.ReentrantLock; @@ -53,9 +52,8 @@ public class ConcurrentFileExtractor extends FileExtractor { * * @param fileLocator locates a filesystem inside a zip compression * @param destination an absolute filesystem path representing the extraction destination filesystem - * @throws FileNotFoundException if the destination filesystem path is not found */ - public ConcurrentFileExtractor(FileLocator fileLocator, String destination) throws FileNotFoundException { + public ConcurrentFileExtractor(FileLocator fileLocator, String destination) { super(fileLocator, destination); } From 55e1c73643f391c39e609e4df90cce09e397ddd3 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 06:58:58 -0400 Subject: [PATCH 05/27] LibraryInfo.(...): introduced directory path for the extraction path --- .../snaploader/LibraryInfo.java | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/LibraryInfo.java b/snaploader/src/main/java/electrostatic4j/snaploader/LibraryInfo.java index 3d16cc9..09f0a7b 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/LibraryInfo.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/LibraryInfo.java @@ -32,6 +32,7 @@ package electrostatic4j.snaploader; +import electrostatic4j.snaploader.filesystem.DirectoryPath; import electrostatic4j.snaploader.platform.NativeDynamicLibrary; /** @@ -62,7 +63,7 @@ public final class LibraryInfo { private String jarPath; private String directory; private String baseName; - private String extractionDir; + private DirectoryPath directoryPath; /** * Instantiates a library info data structure pointing to a library in the classpath. @@ -71,11 +72,11 @@ public final class LibraryInfo { * this is used as a backup directory path * in case the {@link NativeDynamicLibrary#getPlatformDirectory()} is not valid. * @param baseName the library basename, for example, 'lib-basename.so'. - * @param extractionDir the extraction destination in absolute string format, "null" if the current [user.dir] is + * @param directoryPath the extraction destination in absolute string format, "null" if the current [user.dir] is * specified as the extraction directory */ - public LibraryInfo(String directory, String baseName, String extractionDir) { - this(null, directory, baseName, extractionDir); + public LibraryInfo(String directory, String baseName, DirectoryPath directoryPath) { + this(null, directory, baseName, directoryPath); } /** @@ -86,14 +87,13 @@ public LibraryInfo(String directory, String baseName, String extractionDir) { * this is used as a backup directory path * in case the {@link NativeDynamicLibrary#getPlatformDirectory()} is not valid. * @param baseName the library basename, for example, 'lib-basename.so'. - * @param extractionDir the extraction destination in absolute string format, "null" if the current [user.dir] is - * specified as the extraction directory + * @param directoryPath the extraction destination in absolute string format */ - public LibraryInfo(String jarPath, String directory, String baseName, String extractionDir) { + public LibraryInfo(String jarPath, String directory, String baseName, DirectoryPath directoryPath) { this.jarPath = jarPath; this.directory = directory; this.baseName = baseName; - this.extractionDir = extractionDir; + this.directoryPath = directoryPath; } /** @@ -129,11 +129,10 @@ public String getDirectory() { /** * Retrieves the extraction absolute directory. * - * @return the extraction destination in absolute string format, "null" if the current [user.dir] is - * specified as the extraction directory + * @return the extraction destination in absolute string format */ - public String getExtractionDir() { - return extractionDir; + public DirectoryPath getExtractionDirectory() { + return directoryPath; } /** @@ -171,10 +170,10 @@ public void setBaseName(final String baseName) { * Sets the extraction directory used for extracting the native dynamic library in the * form of an absolute directory, "null" to use the current [user.dir]. * - * @param extractionDir the absolute extraction directory to which the located library - * will be extracted to, "null" to set the extraction to the current [user.dir] + * @param directoryPath the absolute extraction directory to which the located library + * will be extracted to */ - public void setExtractionDir(String extractionDir) { - this.extractionDir = extractionDir; + public void setExtractionDirectory(DirectoryPath directoryPath) { + this.directoryPath = directoryPath; } } From 8285767bd38a0632b57685fb318c77c7e366f6b9 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 07:00:33 -0400 Subject: [PATCH 06/27] NativeDynamicLibrary: applied API changes --- .../snaploader/platform/NativeDynamicLibrary.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/platform/NativeDynamicLibrary.java b/snaploader/src/main/java/electrostatic4j/snaploader/platform/NativeDynamicLibrary.java index e716c45..967687b 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/platform/NativeDynamicLibrary.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/platform/NativeDynamicLibrary.java @@ -35,6 +35,7 @@ import java.io.File; import electrostatic4j.snaploader.LibraryInfo; import electrostatic4j.snaploader.NativeBinaryLoader; +import electrostatic4j.snaploader.filesystem.DirectoryPath; import electrostatic4j.snaploader.platform.util.NativeVariant; import electrostatic4j.snaploader.platform.util.PlatformPredicate; import electrostatic4j.snaploader.platform.util.PropertiesProvider; @@ -69,7 +70,7 @@ public class NativeDynamicLibrary { * A designator for the extraction directory of the * native library. */ - protected String extractionDir; + protected DirectoryPath directoryPath; /** * The platform-specific predicate; that if evaluated as @@ -137,7 +138,7 @@ public void initWithLibraryInfo(LibraryInfo libraryInfo) { jarPath = libraryInfo.getJarPath(); /* Initializes the library with an extraction path, "null" to extract to the current user directory */ - extractionDir = libraryInfo.getExtractionDir(); + directoryPath = libraryInfo.getExtractionDirectory(); /* Fallback initializes the library directory within the jar from the library-info */ if (platformDirectory == null) { @@ -178,11 +179,8 @@ public String getCompressedLibrary() { * @return the absolute path composed of the extraction directory and the library name and system-specific extension */ public String getExtractedLibrary() { - if (extractionDir != null) { - return extractionDir + PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + libraryFile; - } - return PropertiesProvider.USER_DIR.getSystemProperty() + - PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + libraryFile; + return directoryPath.getPath() + + PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + libraryFile; } /** From 4a648f37286cf8a0c6864d148ab1ffd73216f53c Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 07:00:49 -0400 Subject: [PATCH 07/27] snaploader-examples: applied API changes --- .../snaploader/examples/TestBasicFeatures.java | 10 ++++------ .../snaploader/examples/TestBasicFeatures2.java | 4 ++-- .../snaploader/examples/TestFilesystemException.java | 3 ++- .../snaploader/examples/TestZipExtractor.java | 2 -- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java index 9996957..e8156ee 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java @@ -32,10 +32,9 @@ package electrostatic4j.snaploader.examples; -import java.io.IOException; - import electrostatic4j.snaploader.LibraryInfo; import electrostatic4j.snaploader.NativeBinaryLoader; +import electrostatic4j.snaploader.filesystem.DirectoryPath; import electrostatic4j.snaploader.platform.util.DefaultDynamicLibraries; import electrostatic4j.snaploader.platform.NativeDynamicLibrary; import electrostatic4j.snaploader.platform.util.NativeVariant; @@ -92,13 +91,12 @@ protected static void printDetails(NativeBinaryLoader loader) { System.out.println("--------------------------------------------------------------"); } - protected static String getLibrariesAbsolutePath() { - return PropertiesProvider.USER_DIR.getSystemProperty() + - PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + "libs"; + protected static DirectoryPath getLibrariesAbsolutePath() { + return new DirectoryPath(PropertiesProvider.USER_DIR.getSystemProperty(), "libs"); } protected static String getJarFilePath() { - return getLibrariesAbsolutePath() + + return getLibrariesAbsolutePath().getPath() + PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + getJarFile(); } diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures2.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures2.java index 5d431b0..dbae343 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures2.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures2.java @@ -32,12 +32,12 @@ package electrostatic4j.snaploader.examples; -import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; import electrostatic4j.snaploader.LibraryInfo; import electrostatic4j.snaploader.NativeBinaryLoader; +import electrostatic4j.snaploader.filesystem.DirectoryPath; import electrostatic4j.snaploader.platform.util.DefaultDynamicLibraries; import electrostatic4j.snaploader.platform.NativeDynamicLibrary; import electrostatic4j.snaploader.platform.util.NativeVariant; @@ -60,7 +60,7 @@ public static void main(String[] args) throws Exception { NativeVariant.OS_NAME.getProperty(), NativeVariant.OS_ARCH.getProperty())); final LibraryInfo libraryInfo = new LibraryInfo(compressionPath.toString(), "lib/placeholder", - "jmealloc", extractionPath.toString()); + "jmealloc", new DirectoryPath(extractionPath.toString())); final NativeDynamicLibrary[] libraries = new NativeDynamicLibrary[] { DefaultDynamicLibraries.LINUX_X86, diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemException.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemException.java index 1e041f9..262e138 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemException.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemException.java @@ -3,6 +3,7 @@ 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; @@ -21,7 +22,7 @@ public static void main(String[] args) throws Exception { NativeVariant.OS_NAME.getProperty(), NativeVariant.OS_ARCH.getProperty())); final LibraryInfo libraryInfo = new LibraryInfo(compressionPath.toString(), "lib/placeholder", - "jme3alloc", extractionPath.toString()); + "jme3alloc", new DirectoryPath(extractionPath.toString())); final NativeDynamicLibrary[] libraries = new NativeDynamicLibrary[] { DefaultDynamicLibraries.LINUX_X86, diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java index f95c1c7..087831f 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java @@ -32,8 +32,6 @@ package electrostatic4j.snaploader.examples; -import java.io.IOException; - import electrostatic4j.snaploader.filesystem.FileExtractionListener; import electrostatic4j.snaploader.filesystem.FileExtractor; import electrostatic4j.snaploader.filesystem.FileLocator; From dd25fb8223922fca1c5f73835eb1866ba28ec761 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 07:07:58 -0400 Subject: [PATCH 08/27] snaploader-examples: applied DirectoryPath API changes --- .../snaploader/examples/TestBasicFeatures.java | 2 +- .../snaploader/examples/TestFilesystemMemoryLeak.java | 4 ++-- .../electrostatic4j/snaploader/examples/TestZipExtractor.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java index e8156ee..649f2f4 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java @@ -101,7 +101,7 @@ protected static String getJarFilePath() { } protected static String getNativeDynamicLibraryPath() { - return getLibrariesAbsolutePath() + + return getLibrariesAbsolutePath().getPath() + PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + "lib" + getLibraryBaseName() + ".so"; } diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemMemoryLeak.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemMemoryLeak.java index 9decb74..71a4104 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemMemoryLeak.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemMemoryLeak.java @@ -79,12 +79,12 @@ public void onExtractionFinalization(FileExtractor fileExtractor, FileLocator fi } protected static String getZipAbsolutePath() { - return TestBasicFeatures.getLibrariesAbsolutePath() + + return TestBasicFeatures.getLibrariesAbsolutePath().getPath() + PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + "jmelogo700.zip"; } protected static String getExtractionPath() { - return TestBasicFeatures.getLibrariesAbsolutePath() + + return TestBasicFeatures.getLibrariesAbsolutePath().getPath() + PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + getFilePath(); } diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java index 087831f..fb5dfde 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java @@ -78,12 +78,12 @@ public void onExtractionFinalization(FileExtractor fileExtractor, FileLocator fi } protected static String getZipAbsolutePath() { - return TestBasicFeatures.getLibrariesAbsolutePath() + + return TestBasicFeatures.getLibrariesAbsolutePath().getPath() + PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + "jmelogo700.zip"; } protected static String getExtractionPath() { - return TestBasicFeatures.getLibrariesAbsolutePath() + + return TestBasicFeatures.getLibrariesAbsolutePath().getPath() + PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + getFilePath(); } From 93b60211f362acf5a0c71ef5ef6f72a489e156b0 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 14:14:41 -0400 Subject: [PATCH 09/27] FileLocator: better handling of locators routines - zip-file recognition - ZipStreamProvider --- .../snaploader/filesystem/FileLocator.java | 107 +++++++++++------- 1 file changed, 69 insertions(+), 38 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java index a6906b4..6d448bf 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java @@ -34,7 +34,6 @@ import electrostatic4j.snaploader.throwable.FilesystemResourceInitializationException; import electrostatic4j.snaploader.util.SnapLoaderLogger; - import java.io.*; import java.util.logging.Level; import java.util.zip.ZipEntry; @@ -46,7 +45,7 @@ * * @author pavl_g */ -public class FileLocator implements InputStreamProvider { +public class FileLocator implements ZipStreamProvider { /** * The input stream associated with the located filesystem. @@ -59,12 +58,24 @@ public class FileLocator implements InputStreamProvider { */ protected FileLocalizingListener fileLocalizingListener; - protected String directory; + protected ZipFile compression; + + protected String compressionPath; protected String filePath; protected ZipCompressionType compressionType; + /** + * Locates the library inside the stock jar filesystem. + * This object leaks an input stream. + * + * @param filePath the path to the dynamic native library inside that jar filesystem + */ + public FileLocator(String filePath) { + this.filePath = filePath; + } + /** * Locates a filesystem inside an external zip compression, the zip filesystem is defined as a {@link ZipFile} object and * the locatable filesystem is defined as a {@link ZipEntry} object. @@ -72,14 +83,14 @@ public class FileLocator implements InputStreamProvider { * Warning: This object leaks a buffered stream, either use try-with-resources, or handle your * memory manually! * - * @param directory the absolute path for the external jar filesystem + * @param compressionPath the absolute path for the external jar filesystem * @param filePath the path to the filesystem to be extracted * @param compressionType the type of the zip compression, ZIP or JAR * * @throws IOException if the jar to be located is not found or an interrupted I/O exception has occured */ - public FileLocator(String directory, String filePath, ZipCompressionType compressionType) throws IOException { - this.directory = directory; + public FileLocator(String compressionPath, String filePath, ZipCompressionType compressionType) throws IOException { + this.compressionPath = compressionPath; this.filePath = filePath; this.compressionType = compressionType; } @@ -94,53 +105,54 @@ protected FileLocator() { @Override public void initialize(int size) throws IOException { // 1) sanity-check for double initializing - // 2) sanity-check for pre-initialization using other routines - // (e.g., classpath resources stream). if (this.fileInputStream != null) { SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", "File locator already initialized using external routines with hash key #" + getHashKey()); return; } try { - final ZipFile compression = compressionType.createNewCompressionObject(directory); - final ZipEntry zipEntry = compression.getEntry(filePath); - validateFileLocalization(zipEntry); - if (size > 0) { - this.fileInputStream = new BufferedInputStream(compression.getInputStream(zipEntry), size); - SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", - "File locator initialized with hash key #" + getHashKey()); - return; + + // 2) sanity-check for initialization routines + // (e.g., classpath resources stream v.s. external compression). + if (compressionPath == null || compressionType == null) { + classPathRoutine(); + } else { + externalCompressionRoutine(size); + } + + // fire the success listener if the file localization has passed! + if (fileLocalizingListener != null) { + fileLocalizingListener.onFileLocalizationSuccess(this); } - this.fileInputStream = compression.getInputStream(zipEntry); - SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", - "File locator initialized with hash key #" + getHashKey()); } catch (Exception e) { close(); - throw new FilesystemResourceInitializationException( + final FilesystemResourceInitializationException exception = new FilesystemResourceInitializationException( "Failed to initialize the file locator handler #" + getHashKey(), e); + // fire the failure listener when file localization fails and pass + // the causative exception + if (fileLocalizingListener != null) { + fileLocalizingListener.onFileLocalizationFailure(this, exception); + } + throw exception; } } - /** - * Validates the file localization process inside the compression. - * - * @throws FileNotFoundException if the localization of the file inside - * the specified compression has failed. - */ - protected void validateFileLocalization(final ZipEntry zipEntry) throws FileNotFoundException { - if (zipEntry != null) { - if (fileLocalizingListener != null) { - fileLocalizingListener.onFileLocalizationSuccess(this); - } - } else { - final FileNotFoundException fileNotFoundException = - new FileNotFoundException("File locator has failed to locate the file inside the compression!"); + protected void classPathRoutine() { + SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", + "File locator initialized using classpath routine with hash key #" + getHashKey()); + this.fileInputStream = getClass().getResourceAsStream(filePath); + } - if (fileLocalizingListener != null) { - fileLocalizingListener.onFileLocalizationFailure(this, fileNotFoundException); - } - throw fileNotFoundException; + protected void externalCompressionRoutine(int size) throws IOException { + this.compression = compressionType.createNewCompressionObject(compressionPath); + final ZipEntry zipEntry = compression.getEntry(filePath); + if (size > 0) { + this.fileInputStream = new BufferedInputStream(compression.getInputStream(zipEntry), size); + } else { + this.fileInputStream = compression.getInputStream(zipEntry); } + SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", + "File locator initialized using external compression routine with hash key #" + getHashKey()); } @Override @@ -150,10 +162,24 @@ public InputStream getFileInputStream() { @Override public void close() throws IOException { + // this is executed in all routines + // it updates the CleanableResource object + // for the Compression Routines if (fileInputStream != null) { fileInputStream.close(); fileInputStream = null; } + + // this will be bypassed in the case of using other non-compression routines to + // initialize the file streams (e.g., the classpath routines). + if (compression != null) { + // this closes all the streams associated with it (if they are not closed) + // aka. + // the file entries stream + // and the native resources for this object + compression.close(); + compression = null; + } SnapLoaderLogger.log(Level.INFO, getClass().getName(), "close", "File locator #" + getHashKey() + " resources closed!"); } @@ -162,4 +188,9 @@ public void close() throws IOException { public void setFileLocalizingListener(FileLocalizingListener fileLocalizingListener) { this.fileLocalizingListener = fileLocalizingListener; } + + @Override + public ZipFile getCompression() { + return compression; + } } From 97d7f9c0ca3ef3541f6b36aaeafe71b702adac5d Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 14:16:20 -0400 Subject: [PATCH 10/27] ZipStreamProvider: introduced a zip stream provider interface in recognition to the ZipFile native resources --- .../filesystem/ZipStreamProvider.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ZipStreamProvider.java diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ZipStreamProvider.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ZipStreamProvider.java new file mode 100644 index 0000000..52ab65b --- /dev/null +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ZipStreamProvider.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023-2024, 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.filesystem; + +import java.util.zip.ZipFile; + +/** + * A specialization providing a zip file object over the input stream provider + * to locate the files from within. + * + * @author pavl_g + */ +public interface ZipStreamProvider extends InputStreamProvider { + + /** + * Retrieves the compression used to locate the files. + * + * @return a zip filesystem object + */ + ZipFile getCompression(); +} From 9d2267ab71ef789a90baf693959e2345d8ad0264 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 14:16:53 -0400 Subject: [PATCH 11/27] DirectoryPath: fix the USER_HOME alias - added CLASS_PATH alias --- .../snaploader/filesystem/DirectoryPath.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/DirectoryPath.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/DirectoryPath.java index f63c167..3e560aa 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/DirectoryPath.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/DirectoryPath.java @@ -51,7 +51,15 @@ public final class DirectoryPath { * An alias object for the root user home directory absolute path. */ public static final DirectoryPath USER_HOME = - new DirectoryPath(PropertiesProvider.USER_DIR.getSystemProperty()); + new DirectoryPath(PropertiesProvider.USER_HOME.getSystemProperty()); + + /** + * When combined with the + * {@link electrostatic4j.snaploader.LibraryInfo#LibraryInfo(DirectoryPath, DirectoryPath, String, DirectoryPath)} + * and the {@link electrostatic4j.snaploader.NativeBinaryLoader} + * APIs, it denotes the classpath routine for the {@link FileLocator} API. + */ + public static final DirectoryPath CLASS_PATH = new DirectoryPath(null); private String path; From 6e1d2ebf2de0f554a07e83058f22cc8f5019937a Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 14:18:10 -0400 Subject: [PATCH 12/27] LibraryLocator.(String): dispatch to the FileLocator classpath routine --- .../java/electrostatic4j/snaploader/library/LibraryLocator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryLocator.java index 2834e81..670b957 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryLocator.java @@ -52,7 +52,7 @@ public class LibraryLocator extends FileLocator { * @param libraryPath the path to the dynamic native library inside that jar filesystem */ public LibraryLocator(String libraryPath) { - this.fileInputStream = LibraryLocator.class.getClassLoader().getResourceAsStream(libraryPath); + super(libraryPath); } /** From 8cc3cfc04b2f54f6a8fbb0a9a4b2b5993f92ea03 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 14:18:53 -0400 Subject: [PATCH 13/27] LibraryInfo: introduced DirectoryPath API for the rest of paths --- .../snaploader/LibraryInfo.java | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/LibraryInfo.java b/snaploader/src/main/java/electrostatic4j/snaploader/LibraryInfo.java index 09f0a7b..790c0d3 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/LibraryInfo.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/LibraryInfo.java @@ -60,8 +60,8 @@ */ public final class LibraryInfo { - private String jarPath; - private String directory; + private DirectoryPath jarPath; + private DirectoryPath directory; private String baseName; private DirectoryPath directoryPath; @@ -71,25 +71,29 @@ public final class LibraryInfo { * @param directory the platform-independent directory inside the compression used for locating the native dynamic library, * this is used as a backup directory path * in case the {@link NativeDynamicLibrary#getPlatformDirectory()} is not valid. - * @param baseName the library basename, for example, 'lib-basename.so'. - * @param directoryPath the extraction destination in absolute string format, "null" if the current [user.dir] is - * specified as the extraction directory + * @param baseName the library basename, for example, 'lib-basename.so' (not null). + * @param directoryPath the extraction destination path, {@link DirectoryPath#USER_DIR} for + * a user working directory extraction path, + * and {@link DirectoryPath#USER_HOME} for the user home (not null). */ - public LibraryInfo(String directory, String baseName, DirectoryPath directoryPath) { - this(null, directory, baseName, directoryPath); + public LibraryInfo(DirectoryPath directory, String baseName, DirectoryPath directoryPath) { + this(DirectoryPath.CLASS_PATH, directory, baseName, directoryPath); } /** * Instantiates a library info data structure pointing to a library in an external jar with jarPath. * - * @param jarPath a path to an external jar to locate the library inside, "null" to use the project jar (classpath). + * @param jarPath a path to an external jar to locate the library inside, {@link DirectoryPath#CLASS_PATH} to assign the classpath routine + * to the {@link electrostatic4j.snaploader.filesystem.FileLocator} API (not null). * @param directory the platform-independent directory inside the compression used for locating the native dynamic library, * this is used as a backup directory path * in case the {@link NativeDynamicLibrary#getPlatformDirectory()} is not valid. - * @param baseName the library basename, for example, 'lib-basename.so'. - * @param directoryPath the extraction destination in absolute string format + * @param baseName the library basename, for example, 'lib-basename.so' (not null). + * @param directoryPath the extraction destination path, {@link DirectoryPath#USER_DIR} for + * a user working directory extraction path, + * and {@link DirectoryPath#USER_HOME} for the user home (not null). */ - public LibraryInfo(String jarPath, String directory, String baseName, DirectoryPath directoryPath) { + public LibraryInfo(DirectoryPath jarPath, DirectoryPath directory, String baseName, DirectoryPath directoryPath) { this.jarPath = jarPath; this.directory = directory; this.baseName = baseName; @@ -109,27 +113,25 @@ public String getBaseName() { * Retrieves the jar filesystem path, the jar is the compression used to locate the native dynamic library to * be extracted and loaded by {@link NativeBinaryLoader}. * - * @return the jar absolute filesystem path in a string format, "null" if the classpath is specified instead of - * an external jar compression + * @return the jar absolute filesystem path object. */ - public String getJarPath() { + public DirectoryPath getJarPath() { return jarPath; } /** * Retrieves the directory inside the compression used for locating the native dynamic library. * - * @return the path to the dynamic library filesystem inside the compression, "null" if the - * default variant-based directories are set to be used + * @return the path to the dynamic library filesystem inside the compression. */ - public String getDirectory() { + public DirectoryPath getDirectory() { return directory; } /** * Retrieves the extraction absolute directory. * - * @return the extraction destination in absolute string format + * @return the extraction destination path object. */ public DirectoryPath getExtractionDirectory() { return directoryPath; @@ -139,10 +141,10 @@ public DirectoryPath getExtractionDirectory() { * Sets the absolute path to the jar filesystem to locate the native dynamic library to be * extracted and loaded, "null" to use the "classpath (the stock jar)"" to load the library filesystem. * - * @param jarPath the absolute path to the jar filesystem to locate the library to be extracted, "null" to - * use the "classpath" (aka. the stock jar) + * @param jarPath the external jar path object to localize the compression, use {@link DirectoryPath#CLASS_PATH} + * to switch the file locator to the classpath routine. */ - public void setJarPath(String jarPath) { + public void setJarPath(DirectoryPath jarPath) { this.jarPath = jarPath; } @@ -150,10 +152,9 @@ public void setJarPath(String jarPath) { * Sets the directory to the native dynamic library inside the jar compression, "null" to use * the default directories specified for each variant by {@link NativeBinaryLoader}. * - * @param directory the location to the native dynamic library inside the jar compression, "null" - * to use the default variant-based directories + * @param directory the location to the native dynamic library inside the jar compression. */ - public void setDirectory(String directory) { + public void setDirectory(DirectoryPath directory) { this.directory = directory; } @@ -167,11 +168,10 @@ public void setBaseName(final String baseName) { } /** - * Sets the extraction directory used for extracting the native dynamic library in the - * form of an absolute directory, "null" to use the current [user.dir]. + * Sets the extraction directory used for extracting the native dynamic library. * - * @param directoryPath the absolute extraction directory to which the located library - * will be extracted to + * @param directoryPath the extraction directory path to which the native-located library + * will be extracted to. */ public void setExtractionDirectory(DirectoryPath directoryPath) { this.directoryPath = directoryPath; From 125a95b26295199d03618c70fed2b3738c3065bb Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 14:20:19 -0400 Subject: [PATCH 14/27] NativeDynamicLibrary: applied API changes --- .../snaploader/platform/NativeDynamicLibrary.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/platform/NativeDynamicLibrary.java b/snaploader/src/main/java/electrostatic4j/snaploader/platform/NativeDynamicLibrary.java index 967687b..695712e 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/platform/NativeDynamicLibrary.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/platform/NativeDynamicLibrary.java @@ -135,14 +135,14 @@ public void initWithLibraryInfo(LibraryInfo libraryInfo) { } /* Initializes the library jar path to locate before extracting, "null" to use the classpath */ - jarPath = libraryInfo.getJarPath(); + jarPath = libraryInfo.getJarPath().getPath(); /* Initializes the library with an extraction path, "null" to extract to the current user directory */ directoryPath = libraryInfo.getExtractionDirectory(); /* Fallback initializes the library directory within the jar from the library-info */ if (platformDirectory == null) { - platformDirectory = libraryInfo.getDirectory(); + platformDirectory = libraryInfo.getDirectory().getPath(); } } From 7e003f5ab4bcbc3683c68ac2494d3a38f4113e07 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 14:20:43 -0400 Subject: [PATCH 15/27] snaploader-examples: applied API changes --- .../snaploader/examples/TestBasicFeatures.java | 7 +++---- .../snaploader/examples/TestBasicFeatures2.java | 2 +- .../snaploader/examples/TestFilesystemException.java | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java index 649f2f4..bd4674c 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures.java @@ -50,7 +50,7 @@ public final class TestBasicFeatures { protected static final LibraryInfo libraryInfo = new LibraryInfo(getJarFilePath(), - "lib/placeholder", + new DirectoryPath(DefaultDynamicLibraries.LINUX_X86.getPlatformDirectory()), getLibraryBaseName(), getLibrariesAbsolutePath()); @@ -95,9 +95,8 @@ protected static DirectoryPath getLibrariesAbsolutePath() { return new DirectoryPath(PropertiesProvider.USER_DIR.getSystemProperty(), "libs"); } - protected static String getJarFilePath() { - return getLibrariesAbsolutePath().getPath() + - PropertiesProvider.FILE_SEPARATOR.getSystemProperty() + getJarFile(); + protected static DirectoryPath getJarFilePath() { + return new DirectoryPath(getLibrariesAbsolutePath().getPath(), getJarFile()); } protected static String getNativeDynamicLibraryPath() { diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures2.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures2.java index dbae343..8be00b9 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures2.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestBasicFeatures2.java @@ -59,7 +59,7 @@ public static void main(String[] args) throws Exception { 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(compressionPath.toString(), "lib/placeholder", + final LibraryInfo libraryInfo = new LibraryInfo(new DirectoryPath(compressionPath.toString()), new DirectoryPath("lib/placeholder"), "jmealloc", new DirectoryPath(extractionPath.toString())); final NativeDynamicLibrary[] libraries = new NativeDynamicLibrary[] { diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemException.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemException.java index 262e138..60b3605 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemException.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemException.java @@ -21,7 +21,7 @@ public static void main(String[] args) throws Exception { 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(compressionPath.toString(), "lib/placeholder", + final LibraryInfo libraryInfo = new LibraryInfo(new DirectoryPath(compressionPath.toString()), new DirectoryPath("lib/placeholder"), "jme3alloc", new DirectoryPath(extractionPath.toString())); final NativeDynamicLibrary[] libraries = new NativeDynamicLibrary[] { From a3a48504d17cca69d80a4a61a8e35b29bb0dcbf5 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 16:31:34 -0400 Subject: [PATCH 16/27] Removed ZipCompressionType.java --- .../filesystem/ZipCompressionType.java | 109 ------------------ 1 file changed, 109 deletions(-) delete mode 100644 snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ZipCompressionType.java diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ZipCompressionType.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ZipCompressionType.java deleted file mode 100644 index 09e1bae..0000000 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/ZipCompressionType.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2023-2024, 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.filesystem; - -import java.io.IOException; -import java.util.jar.JarFile; -import java.util.zip.ZipFile; - -/** - * A creational pattern that defines a zip compression type and creates - * a compression object accordingly. - * - * @author pavl_g - */ -public enum ZipCompressionType { - - /** - * A {@link ZipFile} compression type. - */ - ZIP(0x00, null), - - /** - * A {@link JarFile} compression type. - */ - JAR(0xFF, null); - - private final int compressionSymbol; - private ZipFile compressionObject; - - /** - * Defines a zip compression type with a symbol and a representative object. - * - * @param compressionSymbol a unique hex code representing the compression type object - * @param compressionObject the final required compression object - * @see ZipCompressionType#createNewCompressionObject(String) - */ - ZipCompressionType(final int compressionSymbol, final ZipFile compressionObject) { - this.compressionSymbol = compressionSymbol; - this.compressionObject = compressionObject; - } - - /** - * Creates a new zip compression object by its path based on the compression symbol. - * - * @param directory the zip-filesystem absolute path - * @return a new zip compression object based on the compression type specified by the compression symbol - * @throws IOException if the zip filesystem is not found, or an interrupted I/O operation has occured - */ - protected ZipFile createNewCompressionObject(String directory) throws IOException { - if (compressionObject == null) { - if (this.getCompressionSymbol() == ZipCompressionType.ZIP.getCompressionSymbol()) { - compressionObject = new ZipFile(directory); - return compressionObject; - } - compressionObject = new JarFile(directory); - return compressionObject; - } - return compressionObject; - } - - /** - * Retrieves the unique compression symbol for this compression type. - * - * @return the compression type symbol in integers - */ - protected int getCompressionSymbol() { - return compressionSymbol; - } - - /** - * Retrieves the created zip compression object for this compression type. - * - * @return a {@link ZipFile} compression object or null if {@link ZipCompressionType#createNewCompressionObject(String)} - * isnot invoked on this compression type - */ - public ZipFile getCompressionObject() { - return compressionObject; - } -} From 855a2cb9e908d6f7d70e4962c47e9626d427a1bb Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 16:32:30 -0400 Subject: [PATCH 17/27] FileLocator: simplified dealing with external compression routines --- .../snaploader/filesystem/FileLocator.java | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java index 6d448bf..040b3fa 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java @@ -58,17 +58,19 @@ public class FileLocator implements ZipStreamProvider { */ protected FileLocalizingListener fileLocalizingListener; + /** + * Resembles the compression stream provider object, used in the case of + * external compression routines. + */ protected ZipFile compression; - protected String compressionPath; - + /** + * Resembles the file path inside the compression. + */ protected String filePath; - protected ZipCompressionType compressionType; - /** * Locates the library inside the stock jar filesystem. - * This object leaks an input stream. * * @param filePath the path to the dynamic native library inside that jar filesystem */ @@ -79,20 +81,15 @@ public FileLocator(String filePath) { /** * Locates a filesystem inside an external zip compression, the zip filesystem is defined as a {@link ZipFile} object and * the locatable filesystem is defined as a {@link ZipEntry} object. - *

- * Warning: This object leaks a buffered stream, either use try-with-resources, or handle your - * memory manually! * - * @param compressionPath the absolute path for the external jar filesystem - * @param filePath the path to the filesystem to be extracted - * @param compressionType the type of the zip compression, ZIP or JAR + * @param compression the compression, either {@link ZipFile} or {@link java.util.jar.JarFile} + * @param filePath the path to the filesystem inside the compression to be extracted * - * @throws IOException if the jar to be located is not found or an interrupted I/O exception has occured + * @throws IOException if the jar to be located is not found or an interrupted I/O exception has occurred */ - public FileLocator(String compressionPath, String filePath, ZipCompressionType compressionType) throws IOException { - this.compressionPath = compressionPath; + public FileLocator(ZipFile compression, String filePath) throws IOException { this.filePath = filePath; - this.compressionType = compressionType; + this.compression = compression; } /** @@ -102,6 +99,18 @@ protected FileLocator() { } + /** + * Initializes the input stream provider through a file locator routine, either + * classpath routine or external archive routine. + *

+ * Warning: this stack leaks an input stream provider object for the + * file to be extracted, and the external archive stream provider in case + * of using an external archive routine to locate the file. + * + * @param size the size of the buffered IO in bytes or zero + * for auto filesystem size + * @throws IOException if an I/O error has occurred. + */ @Override public void initialize(int size) throws IOException { // 1) sanity-check for double initializing @@ -114,7 +123,7 @@ public void initialize(int size) throws IOException { // 2) sanity-check for initialization routines // (e.g., classpath resources stream v.s. external compression). - if (compressionPath == null || compressionType == null) { + if (compression == null) { classPathRoutine(); } else { externalCompressionRoutine(size); @@ -137,14 +146,23 @@ public void initialize(int size) throws IOException { } } + /** + * Commands for the classpath routines. + */ protected void classPathRoutine() { SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", "File locator initialized using classpath routine with hash key #" + getHashKey()); this.fileInputStream = getClass().getResourceAsStream(filePath); } + /** + * Commands for the external compression routines. + * + * @param size custom buffer size, zero for auto filesystem size + * (warning: file expansion and truncation rules are applied). + * @throws IOException if an I/O error has occurred. + */ protected void externalCompressionRoutine(int size) throws IOException { - this.compression = compressionType.createNewCompressionObject(compressionPath); final ZipEntry zipEntry = compression.getEntry(filePath); if (size > 0) { this.fileInputStream = new BufferedInputStream(compression.getInputStream(zipEntry), size); From 877fe08bcf9f13db91af1e0cb97600c51b27c8ca Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 16:32:51 -0400 Subject: [PATCH 18/27] library-api: applied API changes --- .../snaploader/library/LibraryExtractor.java | 17 +++++++++-------- .../snaploader/library/LibraryLocator.java | 19 +++++++------------ 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryExtractor.java b/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryExtractor.java index acfa48c..5984ce2 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryExtractor.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryExtractor.java @@ -33,6 +33,7 @@ package electrostatic4j.snaploader.library; import java.io.IOException; +import java.util.zip.ZipFile; import electrostatic4j.snaploader.filesystem.ConcurrentFileExtractor; import electrostatic4j.snaploader.filesystem.FileExtractor; @@ -44,26 +45,26 @@ public class LibraryExtractor extends ConcurrentFileExtractor { /** - * Instantiates a native dynamic library extractor with a jar path, library path and extract destination filesystem path. + * Instantiates a native dynamic library extractor for an external compression file locator routine. * - * @param jarPath an absolute path to the jar filesystem containing the library - * @param libraryPath the path of the library inside the jar filesystem + * @param compression the zip file object for external locator routines + * @param libraryPath the path of the library inside the compression filesystem * @param destination the extraction destination filesystem path * @throws IOException if the jar filesystem to be located is not found, or if the extraction destination is not found */ - public LibraryExtractor(String jarPath, String libraryPath, String destination) throws IOException { - super(new LibraryLocator(jarPath, libraryPath), destination); + public LibraryExtractor(ZipFile compression, String libraryPath, String destination) throws IOException { + super(new LibraryLocator(compression, libraryPath), destination); } /** * Instantiates a native dynamic library extractor with a library path and an extract destination filesystem path. This - * object locates a dynamic native library inside the stock jar filesystem based on a classpath input stream. + * object locates a dynamic native library inside the stock jar filesystem based on a classpath input stream + * (i.e., classpath file locator routine). * * @param libraryPath the path of the library inside the jar filesystem * @param destination the extraction destination filesystem path - * @throws IOException if the jar filesystem to be located is not found, or if the extraction destination is not found */ - public LibraryExtractor(String libraryPath, String destination) throws IOException { + public LibraryExtractor(String libraryPath, String destination) { super(new LibraryLocator(libraryPath), destination); } } diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryLocator.java index 670b957..3e5a590 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/library/LibraryLocator.java @@ -33,9 +33,8 @@ package electrostatic4j.snaploader.library; import java.io.IOException; -import java.util.jar.JarFile; import java.util.zip.ZipEntry; -import electrostatic4j.snaploader.filesystem.ZipCompressionType; +import java.util.zip.ZipFile; import electrostatic4j.snaploader.filesystem.FileLocator; /** @@ -47,7 +46,6 @@ public class LibraryLocator extends FileLocator { /** * Locates the library inside the stock jar filesystem. - * This object leaks an input stream. * * @param libraryPath the path to the dynamic native library inside that jar filesystem */ @@ -56,15 +54,12 @@ public LibraryLocator(String libraryPath) { } /** - * Locates a library inside an external jar, the external jar is defined by the means of a {@link JarFile} and - * the native library is defined as a {@link ZipEntry}. - * This object leaks an input stream. - * - * @param directory the absolute path for the external jar filesystem - * @param libraryPath the path to the dynamic native library inside that jar filesystem - * @throws IOException if the jar to be located is not found or an interrupt I/O operation has occured + * Locates a library inside an external jar, the external jar is defined by the means of a {@link ZipFile} and + * the native library is defined as a {@link ZipEntry}. + * + * @throws IOException if the jar to be located is not found or an interrupt I/O operation has occurred. */ - public LibraryLocator(String directory, String libraryPath) throws IOException { - super(directory, libraryPath, ZipCompressionType.JAR); + public LibraryLocator(ZipFile compression, String filePath) throws IOException { + super(compression, filePath); } } From e323af07a98e07ee3eb4a13ee7c2028c88fc8019 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 16:34:05 -0400 Subject: [PATCH 19/27] NativeBinaryLoader#initializeLibraryExtractor(...): simplified the compression stream provider --- .../java/electrostatic4j/snaploader/NativeBinaryLoader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/NativeBinaryLoader.java b/snaploader/src/main/java/electrostatic4j/snaploader/NativeBinaryLoader.java index c9e3766..1ddc5c6 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/NativeBinaryLoader.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/NativeBinaryLoader.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.jar.JarFile; import java.util.logging.Level; import java.lang.UnsatisfiedLinkError; import electrostatic4j.snaploader.filesystem.FileExtractionListener; @@ -349,7 +350,7 @@ public void onExtractionFinalization(FileExtractor fileExtractor, FileLocator fi protected FileExtractor initializeLibraryExtractor(NativeDynamicLibrary library) throws Exception { FileExtractor extractor; if (library.getJarPath() != null) { - extractor = new LibraryExtractor(library.getJarPath(), library.getCompressedLibrary(), library.getExtractedLibrary()); + extractor = new LibraryExtractor(new JarFile(library.getJarPath()), library.getCompressedLibrary(), library.getExtractedLibrary()); } else { extractor = new LibraryExtractor(library.getCompressedLibrary(), library.getExtractedLibrary()); } From bbd6e8a4f85c9d814bddc791dfd8d440dd57c78c Mon Sep 17 00:00:00 2001 From: pavl_g Date: Tue, 6 Aug 2024 16:34:26 -0400 Subject: [PATCH 20/27] snaploader-examples: applied API changes --- .../snaploader/examples/TestFilesystemMemoryLeak.java | 6 ++---- .../snaploader/examples/TestZipExtractor.java | 5 +++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemMemoryLeak.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemMemoryLeak.java index 71a4104..4e28724 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemMemoryLeak.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestFilesystemMemoryLeak.java @@ -35,13 +35,11 @@ import electrostatic4j.snaploader.filesystem.FileExtractionListener; import electrostatic4j.snaploader.filesystem.FileExtractor; import electrostatic4j.snaploader.filesystem.FileLocator; -import electrostatic4j.snaploader.filesystem.ZipCompressionType; import electrostatic4j.snaploader.platform.util.PropertiesProvider; import electrostatic4j.snaploader.util.SnapLoaderLogger; - -import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.zip.ZipFile; /** * Testing impacts of memory leaks, test this using jconsole. @@ -52,7 +50,7 @@ public class TestFilesystemMemoryLeak { public static void main(String[] args) throws Exception { /* Locates the image inside the Zip Compression */ SnapLoaderLogger.setLoggingEnabled(true); - final FileLocator fileLocator = new FileLocator(getZipAbsolutePath(), getFilePath(), ZipCompressionType.ZIP); + final FileLocator fileLocator = new FileLocator(new ZipFile(getZipAbsolutePath()), getFilePath()); /* Extracts the image filesystem from the Zip Compression */ final FileExtractor fileExtractor = new FileExtractor(fileLocator, getExtractionPath()); fileLocator.initialize(0); diff --git a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java index fb5dfde..f03cf65 100644 --- a/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java +++ b/snaploader-examples/src/main/java/electrostatic4j/snaploader/examples/TestZipExtractor.java @@ -35,10 +35,11 @@ import electrostatic4j.snaploader.filesystem.FileExtractionListener; import electrostatic4j.snaploader.filesystem.FileExtractor; import electrostatic4j.snaploader.filesystem.FileLocator; -import electrostatic4j.snaploader.filesystem.ZipCompressionType; import electrostatic4j.snaploader.platform.util.PropertiesProvider; import electrostatic4j.snaploader.throwable.FilesystemResourceScavengingException; +import java.util.zip.ZipFile; + /** * Tests extracting an image compression from a Zip compression type filesystem using {@link FileExtractor} API. * @@ -48,7 +49,7 @@ public class TestZipExtractor { public static void main(String[] args) throws Exception { /* Locates the image inside the Zip Compression */ - final FileLocator fileLocator = new FileLocator(getZipAbsolutePath(), getFilePath(), ZipCompressionType.ZIP); + final FileLocator fileLocator = new FileLocator(new ZipFile(getZipAbsolutePath()), getFilePath()); /* Extracts the image filesystem from the Zip Compression */ final FileExtractor fileExtractor = new FileExtractor(fileLocator, getExtractionPath()); fileLocator.initialize(0); From fdcfe4929031360847d57b99fdb949707d8eac20 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Wed, 7 Aug 2024 16:33:27 -0400 Subject: [PATCH 21/27] FileLocator#classPathRoutine(): use the AppClassLoader directly instead of the Class#getResourceAsStream(...) algorithm --- .../electrostatic4j/snaploader/filesystem/FileLocator.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java index 040b3fa..c806e10 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java @@ -152,7 +152,12 @@ public void initialize(int size) throws IOException { protected void classPathRoutine() { SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", "File locator initialized using classpath routine with hash key #" + getHashKey()); - this.fileInputStream = getClass().getResourceAsStream(filePath); + // use the AppClassLoader, a BuiltinClassLoader to get the resources from the classpath + // notice that the JVM Classloaders are arranged in a tree-like structure + // 1) The BootStrap ClassLoader is the most ancestor + // 2) The Java Platform ClassLoader is the next in the tree. + // 3) The AppClassLoader is the last in the tree. + this.fileInputStream = getClass().getClassLoader().getResourceAsStream(filePath); } /** From d140d9e32cdbd3d30395edaf4155f191943e711c Mon Sep 17 00:00:00 2001 From: pavl_g Date: Wed, 7 Aug 2024 16:34:19 -0400 Subject: [PATCH 22/27] FileLocator: docs about ClassLoaders --- .../electrostatic4j/snaploader/filesystem/FileLocator.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java index c806e10..810ca8b 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java @@ -152,11 +152,15 @@ public void initialize(int size) throws IOException { protected void classPathRoutine() { SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", "File locator initialized using classpath routine with hash key #" + getHashKey()); - // use the AppClassLoader, a BuiltinClassLoader to get the resources from the classpath + // Use the AppClassLoader, a BuiltinClassLoader to get the resources from the classpath // notice that the JVM Classloaders are arranged in a tree-like structure // 1) The BootStrap ClassLoader is the most ancestor // 2) The Java Platform ClassLoader is the next in the tree. // 3) The AppClassLoader is the last in the tree. + // So, each one backs up to its ancestor! + // However, all those classloaders are loaded by the BootStrap, so if + // getClassLoader() is invoked on them, it will return "null" pointer + // indicating the invalidity of active loaders this.fileInputStream = getClass().getClassLoader().getResourceAsStream(filePath); } From 100aad73b286c14ecfa190753061f76b1d6982c8 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Wed, 7 Aug 2024 16:34:53 -0400 Subject: [PATCH 23/27] NativeBinaryLoader: optimizations --- .../java/electrostatic4j/snaploader/NativeBinaryLoader.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/NativeBinaryLoader.java b/snaploader/src/main/java/electrostatic4j/snaploader/NativeBinaryLoader.java index 1ddc5c6..6bdf0d0 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/NativeBinaryLoader.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/NativeBinaryLoader.java @@ -350,8 +350,10 @@ public void onExtractionFinalization(FileExtractor fileExtractor, FileLocator fi protected FileExtractor initializeLibraryExtractor(NativeDynamicLibrary library) throws Exception { FileExtractor extractor; if (library.getJarPath() != null) { + // use an extractor with the external jar routine extractor = new LibraryExtractor(new JarFile(library.getJarPath()), library.getCompressedLibrary(), library.getExtractedLibrary()); } else { + // use an extractor with the classpath routine extractor = new LibraryExtractor(library.getCompressedLibrary(), library.getExtractedLibrary()); } extractor.initialize(0); @@ -364,7 +366,7 @@ protected LibraryLocator preInitLibraryLocator(FileExtractor extractor) { extractor.getFileLocator().setFileLocalizingListener(new FileLocalizingListener() { @Override public void onFileLocalizationSuccess(FileLocator locator) { - SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initializeLibraryExtractor", + SnapLoaderLogger.log(Level.INFO, getClass().getName(), "preInitLibraryLocator", "Locating native libraries has succeeded!"); // bind the library locator lifecycle to the user application @@ -375,7 +377,7 @@ public void onFileLocalizationSuccess(FileLocator locator) { @Override public void onFileLocalizationFailure(FileLocator locator, Throwable throwable) { - SnapLoaderLogger.log(Level.SEVERE, getClass().getName(), "initializeLibraryExtractor", + SnapLoaderLogger.log(Level.SEVERE, getClass().getName(), "preInitLibraryLocator", "Locating native libraries has failed!", throwable); try { extractor.close(); From b1b43428cc85774679c3115c6e5ff3aba4c0003a Mon Sep 17 00:00:00 2001 From: pavl_g Date: Wed, 7 Aug 2024 17:16:41 -0400 Subject: [PATCH 24/27] FileLocator#classPathRoutine(): assertion against null pointers --- .../java/electrostatic4j/snaploader/filesystem/FileLocator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java index 810ca8b..c93b3bc 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java @@ -162,6 +162,8 @@ protected void classPathRoutine() { // getClassLoader() is invoked on them, it will return "null" pointer // indicating the invalidity of active loaders this.fileInputStream = getClass().getClassLoader().getResourceAsStream(filePath); + assert (this.fileInputStream != null): + "Classpath Routine failed: the file is not in the classpath!"; } /** From 8e5a9e1c70879f141a21af63899ac2efcd664194 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Wed, 7 Aug 2024 17:18:55 -0400 Subject: [PATCH 25/27] FileLocator#classPathRoutine(): refactored the assertion to the FilesystemResourceInitializationException --- .../snaploader/filesystem/FileLocator.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java index c93b3bc..3043bd9 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java @@ -148,8 +148,10 @@ public void initialize(int size) throws IOException { /** * Commands for the classpath routines. + * + * @throws FilesystemResourceInitializationException if the classpath routine fails to locate the file. */ - protected void classPathRoutine() { + protected void classPathRoutine() throws FilesystemResourceInitializationException { SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", "File locator initialized using classpath routine with hash key #" + getHashKey()); // Use the AppClassLoader, a BuiltinClassLoader to get the resources from the classpath @@ -162,8 +164,9 @@ protected void classPathRoutine() { // getClassLoader() is invoked on them, it will return "null" pointer // indicating the invalidity of active loaders this.fileInputStream = getClass().getClassLoader().getResourceAsStream(filePath); - assert (this.fileInputStream != null): - "Classpath Routine failed: the file is not in the classpath!"; + if (this.fileInputStream == null) { + throw new FilesystemResourceInitializationException("Classpath Routine failed: the file is not in the classpath!"); + } } /** From fc6891ca3fc917063bdf8daad9cd49bda59fda43 Mon Sep 17 00:00:00 2001 From: pavl_g Date: Wed, 7 Aug 2024 17:40:50 -0400 Subject: [PATCH 26/27] Simplified exceptions throwing using a Validator API --- .../snaploader/filesystem/FileExtractor.java | 3 + .../snaploader/filesystem/FileLocator.java | 14 ++-- .../util/StreamObjectValidator.java | 64 +++++++++++++++++++ 3 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 snaploader/src/main/java/electrostatic4j/snaploader/util/StreamObjectValidator.java diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileExtractor.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileExtractor.java index 56d9c18..db394bb 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileExtractor.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileExtractor.java @@ -34,6 +34,8 @@ import electrostatic4j.snaploader.throwable.FilesystemResourceInitializationException; import electrostatic4j.snaploader.util.SnapLoaderLogger; +import electrostatic4j.snaploader.util.StreamObjectValidator; + import java.io.*; import java.util.logging.Level; @@ -133,6 +135,7 @@ public void extract() throws IOException, FileNotFoundException { * pipe, and allocate memory according to the active bytes manipulated * by the pipeline. */ InputStream fileStream = fileLocator.getFileInputStream(); + StreamObjectValidator.validateAndThrow(fileStream, StreamObjectValidator.BROKEN_FILE_LOCATOR_PROVIDER); /* Extracts the shipped native files */ /* Allocate a byte buffer for the buffered streams */ diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java index 3043bd9..40aef50 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/filesystem/FileLocator.java @@ -34,6 +34,8 @@ import electrostatic4j.snaploader.throwable.FilesystemResourceInitializationException; import electrostatic4j.snaploader.util.SnapLoaderLogger; +import electrostatic4j.snaploader.util.StreamObjectValidator; + import java.io.*; import java.util.logging.Level; import java.util.zip.ZipEntry; @@ -129,20 +131,19 @@ public void initialize(int size) throws IOException { externalCompressionRoutine(size); } + StreamObjectValidator.validateAndThrow(fileInputStream, StreamObjectValidator.BROKEN_FILE_LOCATOR_PROVIDER); + // fire the success listener if the file localization has passed! if (fileLocalizingListener != null) { fileLocalizingListener.onFileLocalizationSuccess(this); } } catch (Exception e) { close(); - final FilesystemResourceInitializationException exception = new FilesystemResourceInitializationException( - "Failed to initialize the file locator handler #" + getHashKey(), e); // fire the failure listener when file localization fails and pass // the causative exception if (fileLocalizingListener != null) { - fileLocalizingListener.onFileLocalizationFailure(this, exception); + fileLocalizingListener.onFileLocalizationFailure(this, e); } - throw exception; } } @@ -164,9 +165,6 @@ protected void classPathRoutine() throws FilesystemResourceInitializationExcepti // getClassLoader() is invoked on them, it will return "null" pointer // indicating the invalidity of active loaders this.fileInputStream = getClass().getClassLoader().getResourceAsStream(filePath); - if (this.fileInputStream == null) { - throw new FilesystemResourceInitializationException("Classpath Routine failed: the file is not in the classpath!"); - } } /** @@ -178,11 +176,13 @@ protected void classPathRoutine() throws FilesystemResourceInitializationExcepti */ protected void externalCompressionRoutine(int size) throws IOException { final ZipEntry zipEntry = compression.getEntry(filePath); + StreamObjectValidator.validateAndThrow(zipEntry, StreamObjectValidator.COMPRESSION_FILE_LOCALIZING_FAIL); if (size > 0) { this.fileInputStream = new BufferedInputStream(compression.getInputStream(zipEntry), size); } else { this.fileInputStream = compression.getInputStream(zipEntry); } + SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)", "File locator initialized using external compression routine with hash key #" + getHashKey()); } diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/util/StreamObjectValidator.java b/snaploader/src/main/java/electrostatic4j/snaploader/util/StreamObjectValidator.java new file mode 100644 index 0000000..cae68d7 --- /dev/null +++ b/snaploader/src/main/java/electrostatic4j/snaploader/util/StreamObjectValidator.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023-2024, 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.util; + +import electrostatic4j.snaploader.filesystem.StreamProvider; +import electrostatic4j.snaploader.throwable.FilesystemResourceInitializationException; + +/** + * Validates the stream providers tokens. + * + * @author pavl_g + */ +public final class StreamObjectValidator { + + public static final String BROKEN_FILE_LOCATOR_PROVIDER = "Broken file locator stream provider!"; + public static final String COMPRESSION_FILE_LOCALIZING_FAIL = "Cannot locate the file entry in the compression!"; + + private StreamObjectValidator() { + } + + public static void validateAndThrow(final StreamProvider object, final String message, final Throwable cause) { + if (object != null) { + return; + } + throw new FilesystemResourceInitializationException(message, cause); + } + + public static void validateAndThrow(final Object object, final String message) { + if (object != null) { + return; + } + throw new FilesystemResourceInitializationException(message); + } +} From 9da88787dad09a19fc9bcfad13766302b46dbc6b Mon Sep 17 00:00:00 2001 From: pavl_g Date: Wed, 7 Aug 2024 17:41:50 -0400 Subject: [PATCH 27/27] SnapLoaderLogger: LICENSE section --- .../snaploader/util/SnapLoaderLogger.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/snaploader/src/main/java/electrostatic4j/snaploader/util/SnapLoaderLogger.java b/snaploader/src/main/java/electrostatic4j/snaploader/util/SnapLoaderLogger.java index a845880..df103c9 100644 --- a/snaploader/src/main/java/electrostatic4j/snaploader/util/SnapLoaderLogger.java +++ b/snaploader/src/main/java/electrostatic4j/snaploader/util/SnapLoaderLogger.java @@ -1,3 +1,35 @@ +/* + * Copyright (c) 2023-2024, 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.util; import java.util.logging.Level;