Skip to content

Commit 848115e

Browse files
authored
Merge pull request #27 from Electrostat-Lab/final-optimizations
Final optimizations: Logging API - StreamProviders API - Memory Logging
2 parents 8c761fe + f1c3b09 commit 848115e

File tree

15 files changed

+393
-93
lines changed

15 files changed

+393
-93
lines changed

snaploader-examples/src/main/java/electrostatic/snaploader/examples/TestFilesystemMemoryLeak.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import electrostatic.snaploader.filesystem.FileLocator;
3838
import electrostatic.snaploader.filesystem.ZipCompressionType;
3939
import electrostatic.snaploader.platform.util.PropertiesProvider;
40+
import electrostatic.snaploader.util.SnapLoaderLogger;
41+
4042
import java.io.IOException;
4143
import java.util.logging.Level;
4244
import java.util.logging.Logger;
@@ -49,9 +51,12 @@
4951
public class TestFilesystemMemoryLeak {
5052
public static void main(String[] args) throws IOException {
5153
/* Locates the image inside the Zip Compression */
54+
SnapLoaderLogger.setLoggingEnabled(true);
5255
final FileLocator fileLocator = new FileLocator(getZipAbsolutePath(), getFilePath(), ZipCompressionType.ZIP);
5356
/* Extracts the image filesystem from the Zip Compression */
5457
final FileExtractor fileExtractor = new FileExtractor(fileLocator, getExtractionPath());
58+
fileLocator.initialize(0);
59+
fileExtractor.initialize(0);
5560
/* CLOSE/CLEAR I/O Resources */
5661
fileExtractor.setExtractionListener(new FileExtractionListener() {
5762
@Override

snaploader-examples/src/main/java/electrostatic/snaploader/examples/TestMultiThreading.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737

3838
import electrostatic.snaploader.LoadingCriterion;
3939
import electrostatic.snaploader.ConcurrentNativeBinaryLoader;
40-
import electrostatic.snaploader.UnSupportedSystemError;
40+
import electrostatic.snaploader.throwable.UnSupportedSystemError;
4141
import electrostatic.snaploader.platform.util.DefaultDynamicLibraries;
4242
import electrostatic.snaploader.platform.NativeDynamicLibrary;
4343

snaploader-examples/src/main/java/electrostatic/snaploader/examples/TestZipExtractor.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import electrostatic.snaploader.filesystem.FileLocator;
4242
import electrostatic.snaploader.filesystem.ZipCompressionType;
4343
import electrostatic.snaploader.platform.util.PropertiesProvider;
44+
import electrostatic.snaploader.throwable.FilesystemResourceScavengingException;
4445

4546
/**
4647
* Tests extracting an image compression from a Zip compression type filesystem using {@link FileExtractor} API.
@@ -54,6 +55,8 @@ public static void main(String[] args) throws IOException {
5455
final FileLocator fileLocator = new FileLocator(getZipAbsolutePath(), getFilePath(), ZipCompressionType.ZIP);
5556
/* Extracts the image filesystem from the Zip Compression */
5657
final FileExtractor fileExtractor = new FileExtractor(fileLocator, getExtractionPath());
58+
fileLocator.initialize(0);
59+
fileExtractor.initialize(0);
5760
/* CLOSE/CLEAR I/O Resources */
5861
fileExtractor.setExtractionListener(new FileExtractionListener() {
5962
@Override
@@ -70,11 +73,8 @@ public void onExtractionFailure(FileExtractor fileExtractor, Throwable throwable
7073
public void onExtractionFinalization(FileExtractor fileExtractor, FileLocator fileLocator) {
7174
try {
7275
fileExtractor.close();
73-
fileLocator.close();
74-
Logger.getLogger(TestZipExtractor.class.getName())
75-
.log(Level.INFO, "Filesystem Resources Closed!");
76-
} catch (IOException e) {
77-
throw new RuntimeException(e);
76+
} catch (Exception e) {
77+
throw new FilesystemResourceScavengingException(e);
7878
}
7979
}
8080
});

snaploader/src/main/java/electrostatic/snaploader/NativeBinaryLoader.java

Lines changed: 35 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import java.util.Arrays;
3737
import java.util.List;
3838
import java.util.logging.Level;
39-
import java.util.logging.Logger;
4039
import java.lang.UnsatisfiedLinkError;
4140
import electrostatic.snaploader.filesystem.FileExtractionListener;
4241
import electrostatic.snaploader.filesystem.FileExtractor;
@@ -46,6 +45,8 @@
4645
import electrostatic.snaploader.library.LibraryLocator;
4746
import electrostatic.snaploader.platform.NativeDynamicLibrary;
4847
import electrostatic.snaploader.platform.util.NativeVariant;
48+
import electrostatic.snaploader.throwable.UnSupportedSystemError;
49+
import electrostatic.snaploader.util.SnapLoaderLogger;
4950

5051
/**
5152
* A cross-platform utility for extracting and loading native binaries based on
@@ -55,11 +56,6 @@
5556
*/
5657
public class NativeBinaryLoader {
5758

58-
/**
59-
* NativeBinaryLoader logger object.
60-
*/
61-
protected static final Logger logger = Logger.getLogger(NativeBinaryLoader.class.getName());
62-
6359
protected final LibraryInfo libraryInfo;
6460

6561
protected List<NativeDynamicLibrary> registeredLibraries;
@@ -82,11 +78,6 @@ public class NativeBinaryLoader {
8278
*/
8379
protected NativeDynamicLibrary nativeDynamicLibrary;
8480

85-
/**
86-
* Flag for enable/disable logging.
87-
*/
88-
protected boolean loggingEnabled;
89-
9081
/**
9182
* Flag for retry loading with clean extract if UnSatisfiedLinkError is thrown.
9283
*/
@@ -173,28 +164,19 @@ public NativeBinaryLoader loadLibrary(LoadingCriterion criterion) throws IOExcep
173164
/**
174165
* Retrieves the native dynamic library object representing the library to extract and load.
175166
*
176-
* @return an object representing the platform dependent native dynamic library
167+
* @return an object representing the platform-dependent native dynamic library
177168
*/
178169
public NativeDynamicLibrary getNativeDynamicLibrary() {
179170
return nativeDynamicLibrary;
180171
}
181172

182173
/**
183174
* Enables the logging for this object, default value is false.
184-
*
175+
*
185176
* @param loggingEnabled true to enable logging, false otherwise
186177
*/
187178
public void setLoggingEnabled(boolean loggingEnabled) {
188-
this.loggingEnabled = loggingEnabled;
189-
}
190-
191-
/**
192-
* Tests the logging flag, default value is false.
193-
*
194-
* @return true if the logging flag is enabled, false otherwise
195-
*/
196-
public boolean isLoggingEnabled() {
197-
return loggingEnabled;
179+
SnapLoaderLogger.setLoggingEnabled(loggingEnabled);
198180
}
199181

200182
/**
@@ -252,26 +234,30 @@ public FileLocalizingListener getLibraryLocalizingListener() {
252234
}
253235

254236
/**
255-
* Loads a native binary using the platform dependent object, for android,
237+
* Loads a native binary using the platform-dependent object, for Android;
256238
* the library is loaded by its basename (variant is managed internally by the android sdk).
257239
*
258240
* @param library the platform-specific library to load
259241
* @throws IOException in case the binary to be extracted is not found on the specified jar
260242
*/
261243
protected void loadBinary(NativeDynamicLibrary library) throws IOException {
262244
try {
263-
/* sanity check for android java vm (the dalvik) */
245+
/* sanity-check for android java vm (the dalvik) */
264246
if (NativeVariant.Os.isAndroid()) {
265247
System.loadLibrary(libraryInfo.getBaseName());
248+
SnapLoaderLogger.log(Level.INFO, getClass().getName(),"loadBinary", "Successfully loaded library for Android: "
249+
+ library.getExtractedLibrary());
266250
return;
267251
}
268252
System.load(library.getExtractedLibrary());
269-
log(Level.INFO, "loadBinary", "Successfully loaded library: " + library.getExtractedLibrary(), null);
253+
SnapLoaderLogger.log(Level.INFO, getClass().getName(),"loadBinary", "Successfully loaded library: "
254+
+ library.getExtractedLibrary());
270255
if (nativeBinaryLoadingListener != null) {
271256
nativeBinaryLoadingListener.onLoadingSuccess(this);
272257
}
273258
} catch (final UnsatisfiedLinkError error) {
274-
log(Level.SEVERE, "loadBinary", "Cannot load the dynamic library: " + library.getExtractedLibrary(), error);
259+
SnapLoaderLogger.log(Level.SEVERE, getClass().getName(), "loadBinary", "Cannot load the dynamic library: "
260+
+ library.getExtractedLibrary(), error);
275261
if (nativeBinaryLoadingListener != null) {
276262
nativeBinaryLoadingListener.onLoadingFailure(this);
277263
}
@@ -289,28 +275,29 @@ protected void loadBinary(NativeDynamicLibrary library) throws IOException {
289275
* Cleanly extracts and loads the native binary to the current [user.dir].
290276
*
291277
* @param library the platform-specific library to extract and load
292-
* @throws IOException in case the binary to be extracted is not found on the specified jar or an
293-
* interrupted I/O operation has occured
278+
* @throws IOException in case the binary to be extracted is not found on the specified jar, or an
279+
* interrupted I/O operation has occurred
294280
*/
295281
protected void cleanExtractBinary(NativeDynamicLibrary library) throws IOException {
296282
libraryExtractor = initializeLibraryExtractor(library);
297-
log(Level.INFO, "cleanExtractBinary", "File extractor handler initialized!", null);
283+
SnapLoaderLogger.log(Level.INFO, getClass().getName(), "cleanExtractBinary",
284+
"File extractor handler initialized!");
298285
/* CLEAR RESOURCES AND RESET OBJECTS ON-EXTRACTION */
299286
libraryExtractor.setExtractionListener(new FileExtractionListener() {
300287
@Override
301288
public void onExtractionCompleted(FileExtractor fileExtractor) {
302289
try {
303290
// free resources
304291
// removes file locks on some OS
305-
libraryExtractor.getFileLocator().close();
306292
libraryExtractor.close();
307293
libraryExtractor = null;
308-
log(Level.INFO, "cleanExtractBinary", "Extracted successfully to " + library.getExtractedLibrary(), null);
309-
log(Level.INFO, "cleanExtractBinary", "Filesystem Resources closed!", null);
294+
SnapLoaderLogger.log(Level.INFO, getClass().getName(), "cleanExtractBinary",
295+
"Extracted successfully to " + library.getExtractedLibrary());
310296
// load the native binary
311297
loadBinary(library);
312298
} catch (Exception e) {
313-
log(Level.SEVERE, "cleanExtractBinary", "Error while loading the binary!", e);
299+
SnapLoaderLogger.log(Level.SEVERE, getClass().getName(), "cleanExtractBinary",
300+
"Error while loading the binary!", e);
314301
}
315302

316303
// bind the extraction lifecycle to the user application
@@ -321,7 +308,8 @@ public void onExtractionCompleted(FileExtractor fileExtractor) {
321308

322309
@Override
323310
public void onExtractionFailure(FileExtractor fileExtractor, Throwable throwable) {
324-
log(Level.SEVERE, "cleanExtractBinary", "Extraction has failed!", throwable);
311+
SnapLoaderLogger.log(Level.SEVERE, getClass().getName(),
312+
"cleanExtractBinary", "Extraction has failed!", throwable);
325313

326314
// bind the extraction lifecycle to the user application
327315
if (libraryExtractionListener != null) {
@@ -332,18 +320,13 @@ public void onExtractionFailure(FileExtractor fileExtractor, Throwable throwable
332320
@Override
333321
public void onExtractionFinalization(FileExtractor fileExtractor, FileLocator fileLocator) {
334322
try {
335-
if (fileLocator != null &&
336-
fileLocator.getFileInputStream() != null) {
337-
fileLocator.close();
338-
log(Level.INFO, "cleanExtractBinary", "File locator Resources closed!", null);
339-
}
340323
if (fileExtractor != null &&
341324
fileExtractor.getFileOutputStream() != null) {
342325
fileExtractor.close();
343-
log(Level.INFO, "cleanExtractBinary", "File extractor Resources closed!", null);
344326
}
345-
} catch (IOException e) {
346-
log(Level.SEVERE, "cleanExtractBinary", "Error while closing the resources!", e);
327+
} catch (Exception e) {
328+
SnapLoaderLogger.log(Level.SEVERE, getClass().getName(),
329+
"cleanExtractBinary", "Error while closing the resources!", e);
347330
}
348331

349332
// bind the extraction lifecycle to the user application
@@ -370,16 +353,18 @@ protected FileExtractor initializeLibraryExtractor(NativeDynamicLibrary library)
370353
} else {
371354
extractor = new LibraryExtractor(library.getCompressedLibrary(), library.getExtractedLibrary());
372355
}
356+
extractor.initialize(0);
373357
final LibraryLocator fileLocator = preInitLibraryLocator(extractor);
374-
fileLocator.initializeLocator();
358+
fileLocator.initialize(0);
375359
return extractor;
376360
}
377361

378362
protected LibraryLocator preInitLibraryLocator(FileExtractor extractor) {
379363
extractor.getFileLocator().setFileLocalizingListener(new FileLocalizingListener() {
380364
@Override
381365
public void onFileLocalizationSuccess(FileLocator locator) {
382-
log(Level.INFO, "initializeLibraryExtractor", "Locating native libraries has succeeded!", null);
366+
SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initializeLibraryExtractor",
367+
"Locating native libraries has succeeded!");
383368

384369
// bind the library locator lifecycle to the user application
385370
if (libraryLocalizingListener != null) {
@@ -389,13 +374,13 @@ public void onFileLocalizationSuccess(FileLocator locator) {
389374

390375
@Override
391376
public void onFileLocalizationFailure(FileLocator locator, Throwable throwable) {
392-
log(Level.SEVERE, "initializeLibraryExtractor", "Locating native libraries has failed!", throwable);
377+
SnapLoaderLogger.log(Level.SEVERE, getClass().getName(), "initializeLibraryExtractor",
378+
"Locating native libraries has failed!", throwable);
393379
try {
394380
extractor.close();
395-
locator.close();
396-
log(Level.INFO, "initializeLibraryExtractor", "Filesystem resources closed!", null);
397-
} catch (IOException e) {
398-
log(Level.SEVERE, "initializeLibraryExtractor", "File locator closure failed!", e);
381+
} catch (Exception e) {
382+
SnapLoaderLogger.log(Level.SEVERE, getClass().getName(),
383+
"initializeLibraryExtractor", "File locator closure failed!", e);
399384
}
400385

401386
// bind the library locator lifecycle to the user application
@@ -406,23 +391,4 @@ public void onFileLocalizationFailure(FileLocator locator, Throwable throwable)
406391
});
407392
return (LibraryLocator) extractor.getFileLocator();
408393
}
409-
410-
/**
411-
* Log data with a level and a throwable (optional).
412-
*
413-
* @param level the logger level
414-
* @param sourceMethod the source of this call
415-
* @param msg a string formatted message to display
416-
* @param throwable optional param for error messages
417-
*/
418-
protected void log(Level level, String sourceMethod, String msg, Throwable throwable) {
419-
if (!isLoggingEnabled()) {
420-
return;
421-
}
422-
if (throwable == null) {
423-
logger.logp(level, this.getClass().getName(), sourceMethod, msg);
424-
} else {
425-
logger.logp(level, this.getClass().getName(), sourceMethod, msg, throwable);
426-
}
427-
}
428394
}

snaploader/src/main/java/electrostatic/snaploader/SystemDetectionListener.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
package electrostatic.snaploader;
3434

3535
import electrostatic.snaploader.platform.NativeDynamicLibrary;
36+
import electrostatic.snaploader.throwable.UnSupportedSystemError;
3637

3738
/**
3839
* Provides executable functions binding the user applications to

snaploader/src/main/java/electrostatic/snaploader/filesystem/FileExtractor.java

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@
3232

3333
package electrostatic.snaploader.filesystem;
3434

35-
import java.io.FileNotFoundException;
36-
import java.io.FileOutputStream;
37-
import java.io.IOException;
38-
import java.io.InputStream;
39-
import java.io.OutputStream;
35+
import electrostatic.snaploader.throwable.FilesystemResourceInitializationException;
36+
import electrostatic.snaploader.util.SnapLoaderLogger;
37+
38+
import java.io.*;
39+
import java.util.logging.Level;
4040

4141
/**
4242
* Extracts a filesystem from a zip compression to a destination filesystem.
@@ -76,7 +76,7 @@ public class FileExtractor implements OutputStreamProvider {
7676
*/
7777
public FileExtractor(FileLocator fileLocator, String destination) throws FileNotFoundException {
7878
this.fileLocator = fileLocator;
79-
this.fileOutputStream = new FileOutputStream(destination);
79+
this.destination = destination;
8080
}
8181

8282
/**
@@ -85,6 +85,25 @@ public FileExtractor(FileLocator fileLocator, String destination) throws FileNot
8585
protected FileExtractor() {
8686
}
8787

88+
@Override
89+
public void initialize(int size) {
90+
try {
91+
if (size > 0) {
92+
this.fileOutputStream = new BufferedOutputStream(
93+
new FileOutputStream(destination), size);
94+
SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)",
95+
"File extractor initialized with hash key #" + getHashKey());
96+
return;
97+
}
98+
this.fileOutputStream = new FileOutputStream(destination);
99+
SnapLoaderLogger.log(Level.INFO, getClass().getName(), "initialize(int)",
100+
"File extractor initialized with hash key #" + getHashKey());
101+
} catch (FileNotFoundException e) {
102+
throw new FilesystemResourceInitializationException(
103+
"Failed to initialize the file extractor handler #" + getHashKey(), e);
104+
}
105+
}
106+
88107
/**
89108
* Commands and Extract the specified filesystem to the specified destination filesystem.
90109
* <p>
@@ -133,11 +152,21 @@ public void extract() throws IOException, FileNotFoundException {
133152
}
134153

135154
@Override
136-
public void close() throws IOException {
155+
public void close() throws Exception {
137156
if (fileOutputStream != null) {
138157
fileOutputStream.close();
139158
fileOutputStream = null;
140159
}
160+
161+
// close the associated file locator resources
162+
if (getFileLocator() != null && getFileLocator().getFileInputStream() != null) {
163+
getFileLocator().close();
164+
SnapLoaderLogger.log(Level.INFO, getClass().getName(), "close",
165+
"Delegation for file locator resources closure has succeeded!");
166+
}
167+
168+
SnapLoaderLogger.log(Level.INFO, getClass().getName(), "close",
169+
"File extractor #" + getHashKey() + " resources closed!");
141170
}
142171

143172
@Override

0 commit comments

Comments
 (0)