Successfully implemented a complete binary management system for the Fastp Geneious plugin. The FastpBinaryManager class handles detection, extraction, validation, and lifecycle management of bundled fastp and fastplong binaries.
/Users/dho/Documents/geneious-plugin-fastp/src/com/biomatters/plugins/fastp/FastpBinaryManager.java
- Thread-safe singleton instance using synchronized getInstance()
- Ensures only one binary manager exists per JVM
- Extracts binaries from JAR resources at
/binaries/macos/ - Copies to temporary directory created with
Files.createTempDirectory("fastp-plugin-") - Sets executable permissions using
File.setExecutable(true, false) - Handles IOException with proper error messages
- Detects operating system using
System.getProperty("os.name") - Currently supports macOS only
- Throws descriptive IOException for unsupported platforms
- Validates binary exists, is a file, and is executable
- Tests binaries with
--versionflag during initialization - Comprehensive logging at each validation step
getFastpVersion()andgetFastplongVersion()methods- Executes binaries with
--versionflag - Captures and returns version output
- Proper error handling and logging
- Registers JVM shutdown hook for cleanup
cleanup()method deletes temporary binaries and directoryreset()method for forcing re-initializationdeleteOnExit()as fallback cleanup mechanism
- Uses
java.util.logging.Loggerthroughout - Logs initialization, extraction, validation, and cleanup
- Info, warning, and fine log levels appropriately used
- Comprehensive IOException handling
- Cleanup on initialization failure
- InterruptedException handling with thread interrupt restoration
- Detailed error messages for debugging
void initialize()- Extracts and validates binaries- Auto-initializes on first use if not already initialized
File getFastpBinary()- Returns File object for fastpFile getFastplongBinary()- Returns File object for fastplongString getFastpPath()- Returns absolute path to fastpString getFastplongPath()- Returns absolute path to fastplong
boolean isFastpAvailable()- Checks if fastp is readyboolean isFastplongAvailable()- Checks if fastplong is ready
String getFastpVersion()- Gets fastp version by executing itString getFastplongVersion()- Gets fastplong version by executing itString getBinaryInfo()- Returns comprehensive status information
void reset()- Cleans up and resets for re-initialization
private static final String BINARY_RESOURCE_BASE = "/binaries/macos/";
private static final String FASTP_BINARY_NAME = "fastp";
private static final String FASTPLONG_BINARY_NAME = "fastplong";- Creates temp directory:
/tmp/fastp-plugin-{random}/ - Opens resource stream from JAR
- Copies binary using 8KB buffer
- Sets executable permissions
- Validates binary is functional
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
cleanup();
} catch (Exception e) {
logger.log(Level.WARNING, "Error during shutdown cleanup", e);
}
}, "FastpBinaryManager-Cleanup"));Created standalone test: /Users/dho/Documents/geneious-plugin-fastp/test/TestFastpBinaryManager.java
=== FastpBinaryManager Test ===
1. Created BinaryManager instance ✓
2. Initializing (extracting binaries)... ✓
3. Checking binary availability:
Fastp available: true ✓
Fastplong available: true ✓
4. Binary paths:
Fastp: /var/folders/.../fastp-plugin-16388988508373959353/fastp ✓
Fastplong: /var/folders/.../fastp-plugin-16388988508373959353/fastplong ✓
5. Binary validation:
All checks passed ✓
6. Binary versions:
Fastp version: fastp 1.0.1 ✓
Fastplong version: fastplong 0.4.1 ✓
7. Complete binary info: ✓
=== All Tests Passed! ===
- Temporary directories successfully deleted on shutdown
- No leaked temporary files
- Shutdown hook executes correctly
Added resources directory to JAR packaging:
<property name="resources" location="src/main/resources"/>
...
<jar jarfile="${build}/${short-plugin-name}.jar">
<fileset dir="${classes}"/>
<fileset dir="${resources}"/>
<fileset dir="">
<include name="plugin.properties"/>
</fileset>
</jar>binaries/
binaries/macos/
binaries/macos/fastp (1.7M - universal binary)
binaries/macos/fastplong (1.5M - universal binary)
com/biomatters/plugins/fastp/FastpBinaryManager.class
- FastpPlugin.jar: 1.2M
- FastpPlugin.gplugin: 1.2M (identical copy)
- Version: 1.0.1
- Size: 1.7M
- Architecture: Universal (x86_64 + arm64)
- Platform: macOS
- Dependencies: Statically linked (system libraries only)
- Version: 0.4.1
- Size: 1.5M
- Architecture: Universal (x86_64 + arm64)
- Platform: macOS
- Dependencies: Statically linked (system libraries only)
- Singleton pattern with thread safety
- Resource management with try-with-resources
- Proper exception handling and logging
- Defensive validation at every step
- Clean separation of concerns
- Comprehensive JavaDoc documentation
- Idempotent initialization (safe to call multiple times)
- Temporary directory created with secure random suffix
- Files marked for deletion on exit
- Explicit cleanup in shutdown hook
- No hardcoded paths or credentials
- Validates binary integrity before use
- Lazy initialization (extracts only when needed)
- Caching (extracts once, reuses until JVM shutdown)
- Efficient 8KB buffer for binary copying
- Minimal overhead after initialization
// Get singleton instance
FastpBinaryManager manager = FastpBinaryManager.getInstance();
// Initialize (or auto-initializes on first use)
manager.initialize();
// Check availability
if (manager.isFastpAvailable()) {
File fastpBinary = manager.getFastpBinary();
String version = manager.getFastpVersion();
// Use binary for processing
ProcessBuilder pb = new ProcessBuilder(
fastpBinary.getAbsolutePath(),
"-i", inputFile,
"-o", outputFile
);
Process process = pb.start();
// ... handle process
}The FastpExecutor class can now use:
FastpBinaryManager manager = FastpBinaryManager.getInstance();
String fastpPath = manager.getFastpPath();
// Build and execute fastp command-
Multi-platform Support
- Add Windows binaries (fastp.exe, fastplong.exe)
- Add Linux binaries (separate x86_64 and arm64)
- Runtime architecture detection
-
Binary Updates
- Check for binary updates from remote repository
- Download and cache newer versions
- Version compatibility checking
-
Configuration Options
- Allow users to specify custom binary paths
- Persistent configuration storage
- Binary path preferences UI
-
Enhanced Validation
- Checksum verification (SHA-256)
- Binary signature validation
- Compatibility testing with sample data
-
Performance Optimizations
- Reuse temp directory across plugin restarts
- Conditional extraction (check if already extracted)
- Background initialization
The FastpBinaryManager implementation is production-ready and provides:
- ✓ Robust binary management
- ✓ Platform detection and validation
- ✓ Automatic extraction and cleanup
- ✓ Comprehensive error handling
- ✓ Extensive logging for debugging
- ✓ Thread-safe singleton pattern
- ✓ Clean API for integration
- ✓ Successful test execution
The implementation follows enterprise Java best practices and is ready for integration with the FastpExecutor and other plugin components.