A cross-platform tool for managing Sonatype Nexus repositories - available as CLI, GUI (Swing/AWT/Terminal), Android mobile app, and iOS/iPadOS/macOS native apps.
- 📱 Android App: Download APK (Android 8.0+)
- 🍎 iOS/iPadOS App: Download IPA (iOS 16.0+)
- 🖥️ macOS App: Download DMG (macOS 13.0+)
- 💻 Desktop (CLI/GUI): Available via packagecloud.io or build from source
- List components in a repository with optional filtering
- Delete components with safety features (confirmation prompts, dry-run mode)
- Advanced Search & Filtering:
- Regex-based path filtering
- Size range filters (min/max bytes)
- Date range filters (created after/before)
- File extension filtering
- Component name pattern matching
- Repository Statistics:
- Size distribution analysis (5 size buckets)
- File type breakdown by extension
- Age distribution (last 7/30/90 days, older)
- Largest components (top 20)
- Average and median size calculations
- Intelligent caching with 5-minute TTL (reduces server load, faster responses)
- Automatic retry logic with exponential backoff for transient network failures
- Configurable HTTP timeouts via environment variables or properties file
- Verbose and quiet modes for detailed logging or minimal output
- Component metadata extraction:
- Content type, format, creation date, last modified, checksum
- Full metadata in Swing GUI and CLI with
--show-metadata
- Fast startup and minimal dependencies
- Support for environment variables or configuration file
Mobile Apps:
- iOS/iPadOS Native App - Native Swift app with SwiftUI (NEW in v1.0):
- List, search, and delete components on iPhone and iPad
- Advanced filters (size, date, extension, regex)
- Repository statistics with analytics
- Secure Keychain credential storage (AES256 hardware-backed)
- iPad-optimized layouts (split view, landscape support)
- SwiftUI with Material Design patterns
- See iOS README for installation
- Android Mobile App - Native Android app with Jetpack Compose UI (v1.2):
- List, search, and delete components on Android devices
- Advanced filters (size, date, extension, regex)
- Repository statistics with charts
- Secure credential storage with AES256 encryption
- Material Design 3 UI
- See Android README for installation
Desktop Apps:
- macOS Native App - Native Swift app with SwiftUI (NEW in v1.0):
- Sidebar navigation with keyboard shortcuts (⌘L, ⌘R, ⌘F)
- Menu bar integration
- Multi-window support
- Secure Keychain credential storage
- See iOS README for installation
- Swing GUI - Modern graphical interface:
- Advanced filters panel (collapsible)
- Table with 7 metadata columns
- Component details dialog (double-click)
- Statistics dialog with 5 tabs
- AWT GUI - Classic graphical interface for maximum compatibility
- Terminal UI - Full-screen ncurses interface for terminal users
- Command-line interface - For scripting and automation with advanced filters
- Multi-asset components: For components with multiple assets (e.g., JAR + POM + sources), only the first asset's path and size are displayed. This keeps output simple and consistent. Statistics may underreport total repository size for multi-asset components.
- Java 21 or higher
- Maven (or use included Maven wrapper
./mvnw) - Access to a Nexus repository with valid credentials
- Android 8.0+ (API level 26 or higher)
- Gradle 8.2+ (for building from source)
- Access to a Nexus repository with valid credentials
- iOS/iPadOS 16.0 or higher
- Xcode 15.0+ (for building from source)
- Access to a Nexus repository with valid credentials
- macOS 13.0 (Ventura) or higher
- Xcode 15.0+ (for building from source)
- Access to a Nexus repository with valid credentials
./mvnw clean package
This creates an executable JAR at target/jnexus-1.0-jar-with-dependencies.jar.
# Build the debug APK
./gradlew :jnexus-android:assembleDebug
# Or build the release APK (requires signing configuration)
./gradlew :jnexus-android:assembleRelease
The APK will be at jnexus-android/build/outputs/apk/debug/jnexus-android-debug.apk.
Install on your Android device:
adb install jnexus-android/build/outputs/apk/debug/jnexus-android-debug.apk
See the Android README for detailed setup instructions.
Configure your Nexus credentials using either environment variables or a properties file.
export NEXUS_URL=https://your-nexus-server.com
export NEXUS_USER=your-username
export NEXUS_PASSWORD=your-password-or-token
-
Create the configuration directory:
mkdir -p ~/.flossware/nexus -
Copy the example properties file:
cp src/main/resources/jnexus.properties.example ~/.flossware/nexus/nexus.properties -
Edit
~/.flossware/nexus/nexus.propertieswith your credentials:nexus.url=https://your-nexus-server.com nexus.user=your-username nexus.password=your-password-or-token # Optional: UI default values (uncomment to use) #nexus.default.repository=maven-releases #nexus.default.regex=.*SNAPSHOT.* #nexus.default.dryrun=true # Optional: Repository list (comma-separated, for dropdowns/batch operations) #nexus.repositories=maven-releases,maven-snapshots,npm-public,docker-hosted # Optional: HTTP timeout configuration (default: 30 seconds) #nexus.http.timeout.seconds=60The optional defaults will pre-populate the UI fields on startup. The repository list can be used for dropdown menus in GUIs or batch operations.
For managing multiple environments (dev, staging, prod), you can create profile-specific property files:
-
Create profile-specific configuration files:
cp src/main/resources/nexus-dev.properties.example ~/.flossware/nexus/nexus-dev.properties cp src/main/resources/nexus-prod.properties.example ~/.flossware/nexus/nexus-prod.properties -
Edit each file with the appropriate credentials for that environment.
-
Use profiles via environment variable:
export NEXUS_PROFILE=dev ./jnexus.sh list my-repository -
Or via CLI flag:
./jnexus.sh --profile prod list my-repository
Profile naming convention:
- Default:
nexus.properties(no profile specified) - Dev:
nexus-dev.properties(NEXUS_PROFILE=dev or --profile dev) - Production:
nexus-prod.properties(NEXUS_PROFILE=prod or --profile prod) - Staging:
nexus-staging.properties(NEXUS_PROFILE=staging or --profile staging)
This is similar to Spring Boot profiles and allows you to easily switch between environments without editing configuration files.
You can also configure settings via environment variables:
export NEXUS_URL=https://your-nexus-server.com
export NEXUS_USER=your-username
export NEXUS_PASSWORD=your-password-or-token
export NEXUS_HTTP_TIMEOUT=60 # Optional: HTTP timeout in seconds
Environment variables take precedence over properties file values for authentication credentials.
JNexus provides five different interfaces to suit your preference:
- Android Mobile App - Native mobile app (for on-the-go repository management)
- Swing GUI - Modern graphical interface (recommended for desktop users)
- AWT GUI - Classic graphical interface (maximum compatibility)
- Terminal UI - Full-screen ncurses interface (for terminal users)
- Command-line Interface - For scripting and automation
The Android app provides full Nexus repository management on mobile devices:
Installation:
- Install the APK on your Android device (Android 8.0+ required)
- Open the app and navigate to Settings
- Enter your Nexus server URL, username, and password
- Optionally configure repository list and defaults
- Tap Save (credentials are encrypted with AES256)
Features:
- List Screen: Browse components in repositories
- Repository dropdown selector
- List (cached) and Refresh (force update) buttons
- Component cards with size and creation date
- Tap component to view full metadata
- Delete with confirmation dialog
- Search Screen: Advanced filtering
- Size range filters (min/max bytes)
- Date range filters (ISO 8601 format)
- File extension filter
- Component name pattern
- Path regex filter
- Collapsible filter panel
- Stats Screen: Repository analytics
- Total components and size (MB/GB)
- Average and median size
- Size distribution (5 buckets)
- File type breakdown
- Age distribution (7/30/90 days, older)
- Largest components list
- Settings Screen: Configuration
- Nexus URL, username, password
- Repository list (comma-separated)
- Default values (repository, regex, dry-run)
- HTTP timeout
- Encrypted credential storage (AES256_GCM)
Architecture:
- Uses same business logic as desktop versions (jnexus-core shared library)
- OkHttp for HTTP communication
- Jetpack Compose for modern, declarative UI
- Material Design 3 for consistent Android experience
- EncryptedSharedPreferences for secure credential storage
See the Android README for detailed documentation.
The Swing interface provides a modern, native-looking graphical interface:
./jnexus-swing.sh
Features:
- Modern look and feel that matches your operating system
- Responsive design with background task execution
- Table-based display with sortable columns (click header to sort)
- 4 columns: ID, File Size (Bytes), File Size (MB), Path
- Multi-row selection with CTRL/SHIFT click
- Smart Delete Selected button - appears only when rows are selected
- Selection status display - shows total size of selected components
- Summary row - shows total components and bytes (non-editable, highlighted)
- Interactive credential collection - if no configuration files exist, shows a dialog to enter credentials
- Save credentials option - after entering credentials, optionally save them for future use
- Automatic profile selection - if multiple configuration files exist, shows a dialog to choose which one to use
- Repository dropdown selector - choose from "All" or configured repositories (no text field needed)
- Nexus URL display - see which Nexus server you're connected to
- Config file display - see which configuration file is being used
- Regex filter input with Enter key shortcut
- Dry-run checkbox for safe preview of deletions
- List (cached) and Refresh (bypass cache) buttons
- Delete All button with confirmation dialog
- Busy cursor during operations with disabled buttons
- Status bar with operation feedback and selection summary
Screenshot:
┌─────────────────────────────────────────────────────────────────────────────┐
│ Nexus Repository Manager - Swing UI │
├─────────────────────────────────────────────────────────────────────────────┤
│ Repository Configuration │
│ Repository: [maven-releases ▼] (All, maven-releases, npm-public) │
│ Regex Filter: [.*SNAPSHOT.* ] (Enter to List) │
│ ☑ Dry Run (preview only, no actual deletion) │
│ Nexus URL: https://nexus.corp.redhat.com │
│ Config File: ~/.flossware/nexus/nexus.properties │
│ [List] [Refresh] [Delete All] [Delete Selected*] [Clear] [Quit] │
│ *appears when rows selected │
├─────────────────────────────────────────────────────────────────────────────┤
│ Results (Click column headers to sort) │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ ID ▲ File Size (Bytes) ▼ File Size (MB) Path │ │
│ │─────────────────────────────────────────────────────────────────────── │ │
│ │ com.example.app 1,024,567 0.98 path/to/app.jar │ │
│ │ com.example.lib 2,048,123 1.95 path/to/lib.jar ✓ │ │
│ │ com.example.plugin 512,890 0.49 path/to/plugin.jar│ │
│ │ TOTAL: 3 components 3,585,580 3.42 │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────────────────┤
│ Selected: 1 component(s) - 2,048,123 bytes (1.95 MB) │
└─────────────────────────────────────────────────────────────────────────────┘
Features demonstrated:
• Repository dropdown with "All" option (no text field needed)
• 4 columns: ID, File Size (Bytes), File Size (MB), Path
• Sortable columns (click headers to sort)
• Multi-select rows with CTRL/SHIFT (✓ indicates selection)
• Selection status shows total size of selected components
• Delete Selected button appears only when rows are selected
• Summary row with totals (light blue background, non-editable)
• Nexus URL and Config File displayed for reference
• Enter key in Regex Filter triggers List operation
• Busy cursor shows during operations
The AWT interface provides a classic graphical interface using only AWT components:
./jnexus-awt.sh
Features:
- Classic AWT look and feel
- Works on systems where Swing might have issues
- Formatted text output with column headers and summary footer
- Interactive credential collection - if no configuration files exist, shows a dialog to enter credentials
- Save credentials option - after entering credentials, optionally save them to a properties file for future use
- Automatic profile selection - if multiple configuration files exist, shows a dialog to choose which one to use
- Repository dropdown selector - choose from "All" or configured repositories
- Nexus URL display - see which Nexus server you're connected to
- Config file display - see which configuration file is being used
- Regex filter input with Enter key shortcut
- Dry-run checkbox for safe preview of deletions
- Busy cursor during operations with disabled buttons
- Same core functionality as Swing interface
- Lightweight and fast
Screenshot:
┌─────────────────────────────────────────────────────────────────────────────┐
│ Nexus Repository Manager - AWT UI │
├─────────────────────────────────────────────────────────────────────────────┤
│ Repository Configuration │
│ Repository: [maven-releases ▼] (All, maven-releases, npm-public) │
│ Regex Filter: [.*SNAPSHOT.* ] (Enter to List) │
│ ☑ Dry Run (preview only, no actual deletion) │
│ Nexus URL: https://nexus.corp.redhat.com │
│ Config File: ~/.flossware/nexus/nexus.properties │
│ [List] [Refresh] [Delete] [Clear] [Quit] │
├─────────────────────────────────────────────────────────────────────────────┤
│ Results │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ ID File Size Path │ │
│ │ ═══════════════════════════════ ═══════════════ ══════════════════ │ │
│ │ com.example.app-1.0 1,024,567 path/to/app-1.0.jar │ │
│ │ com.example.lib-2.0 2,048,123 path/to/lib-2.0.jar │ │
│ │ com.example.plugin-3.0 512,890 path/to/plugin.jar │ │
│ │ ═══════════════════════════════ ═══════════════ ══════════════════ │ │
│ │ TOTAL: 3 components 3,585,580 (3.42 MB) │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────────────────┤
│ List completed - 3 components - Cached (25s old) │
└─────────────────────────────────────────────────────────────────────────────┘
Why use AWT instead of Swing?
- Maximum compatibility with older Java installations
- Lower memory footprint
- Works well in remote desktop/VNC scenarios
- Familiar to users of classic Java applications
The terminal UI provides a full-screen ncurses interface for terminal users:
./jnexus-ui.sh
Requirements:
- ncurses library installed:
- Ubuntu/Debian:
sudo apt-get install libncurses-dev - Fedora/RHEL:
sudo dnf install ncurses-devel - Arch:
sudo pacman -S ncurses
- Ubuntu/Debian:
Controls:
TAB/ Arrow keys: Navigate between fieldsSPACE/ENTER: Activate buttons or toggle checkboxes- Type directly in text fields
Q/ESC: Quit
Features:
- Interactive credential collection - if no configuration files exist, prompts for credentials via console input (before starting ncurses)
- Save credentials option - after entering credentials, optionally save them to a properties file for future use
- Automatic profile selection - if multiple configuration files exist, shows a text menu to choose which one to use (before starting ncurses)
- Repository selection - shows configured repositories from
nexus.repositoriesproperty (if configured) - Repository name and regex filter inputs
- Dry-run checkbox for safe preview of deletions
- List, Refresh, and Delete buttons
- Live results display with formatted output
- Status messages
Screenshot:
┌────────────────────────────────────────────────────────────────────────────┐
│ Nexus Repository Manager - Terminal UI │
│ │
│ Repository Configuration │
│ Repository: [maven-releases________________] │
│ Regex Filter: [.*SNAPSHOT.*_________________] │
│ [X] Dry Run (preview only, no actual deletion) │
│ │
│ Available Repos: maven-releases, maven-snapshots, npm-public │
│ │
│ [ List ] [ Refresh ] [ Delete ] [ Clear ] [ Quit ] │
│ │
├────────────────────────────────────────────────────────────────────────────┤
│ Results │
│ │
│ ID File Size Path │
│ ═══════════════════════════════ ═══════════════ ═══════════════════ │
│ com.example.app-1.0 1,024,567 path/to/app-1.0.jar │
│ com.example.lib-2.0 2,048,123 path/to/lib-2.0.jar │
│ com.example.plugin-3.0 512,890 path/to/plugin.jar │
│ │
│ │
├────────────────────────────────────────────────────────────────────────────┤
│ List completed - 3 components - Cached (25s old) │
└────────────────────────────────────────────────────────────────────────────┘
Why use Terminal UI?
- Works over SSH without X11 forwarding
- Lightweight and fast
- Familiar to terminal users
- No graphics dependencies beyond ncurses
For scripting and automation, use the traditional CLI:
./jnexus.sh <command> [options]
Or execute the JAR directly:
java -jar target/jnexus-1.0-jar-with-dependencies.jar <command> [options]
List all components in a repository:
./jnexus.sh list my-repository
List components matching a regex pattern:
./jnexus.sh list my-repository ".*SNAPSHOT.*"
WARNING: Delete operations are permanent. Always use --dry-run first!
Preview what would be deleted (dry-run):
./jnexus.sh delete --dry-run my-repository
Delete all components in a repository (with confirmation):
./jnexus.sh delete my-repository
Delete components matching a regex pattern:
./jnexus.sh delete my-repository ".*-1\.0\.0-SNAPSHOT.*"
Skip confirmation prompt:
./jnexus.sh delete --yes my-repository ".*SNAPSHOT.*"
The following options can be used with any command:
Verbose mode - Enable debug logging:
./jnexus.sh --verbose list my-repository
./jnexus.sh -v delete my-repository
Quiet mode - Only show warnings and errors:
./jnexus.sh --quiet list my-repository
./jnexus.sh -q delete my-repository
Profile mode - Use a specific configuration profile:
./jnexus.sh --profile dev list my-repository
./jnexus.sh -p prod delete my-repository
--help,-h- Show help message--version,-V- Show version information--verbose,-v- Enable debug logging--quiet,-q- Only show warnings and errors--profile,-p- Use a specific configuration profile (e.g., dev, prod, staging)--dry-run,-n- (Delete only) Show what would be deleted without deleting--yes,-y- (Delete only) Skip confirmation prompt
# List all snapshots in the releases repository
./jnexus.sh list releases ".*SNAPSHOT.*"
# Dry-run: see what would be deleted
./jnexus.sh delete --dry-run snapshots ".*-2023.*"
# Delete old snapshot versions (with confirmation)
./jnexus.sh delete snapshots ".*-1\.0\..*-SNAPSHOT.*"
# Delete all components in a repository (skip confirmation)
./jnexus.sh delete --yes old-repository
./mvnw test
./mvnw package -DskipTests
src/main/java/org/flossware/jnexus/
├── JNexus.java # Main CLI entry point with Picocli commands
├── NexusClient.java # HTTP client for Nexus API
├── NexusService.java # Business logic for list/delete operations
├── Credentials.java # Configuration management
└── RepoRecord.java # Data model for repository components
src/test/java/org/flossware/jnexus/
├── NexusServiceTest.java # Unit tests for business logic
└── NexusClientTest.java # Tests for client and data models
- Confirmation prompts - Delete operations require explicit confirmation (unless
--yesflag is used) - Dry-run mode - Preview deletions before executing with
--dry-run - Regex filtering - Target specific components instead of entire repositories
- Clear error messages - Helpful feedback when operations fail
- Startup time: < 1 second (vs 3-5 seconds with Spring Boot)
- JAR size: ~5-10 MB (vs ~50 MB with Spring Boot)
- Memory: Minimal footprint, no embedded web server
This project uses X.Y versioning (e.g., 1.0, 1.1, 2.0):
- X (Major): Incompatible API changes or major feature releases
- Y (Minor): New features, bug fixes, or improvements (backwards compatible)
See CHANGELOG.md for release history.
Manual release:
# Bump version, tag, and push
./ci/rev-version.sh
Automated release (CI/CD):
- GitHub Actions: Automatically bumps version, builds, tests, and deploys on push to
main - GitLab CI: Manual pipeline jobs for deployment and release
See CI-CD.md for complete CI/CD documentation.
The ./ci/rev-version.sh script will:
- Increment the minor version (e.g., 1.0 → 1.1)
- Update
pom.xml - Commit the version change
- Create a git tag (e.g.,
v1.1) - Push changes and tag to remote
Desktop Application Credential Storage:
Starting in version 1.30, the desktop application encrypts passwords using JEncrypt - a general-purpose AES-256-GCM encryption library - when stored in ~/.flossware/nexus/nexus.properties.
Encryption Features:
- Passwords automatically encrypted on save using JEncrypt library
- Existing plaintext passwords auto-migrated to encrypted format on next save
- Machine-specific encryption key (PBKDF2-HMAC-SHA256 with 100,000 iterations)
- Credentials tied to hostname and user home directory
- Cannot copy encrypted credentials to other machines
- Backward compatible with older JNexus versions (will see encrypted value as-is)
- Random 12-byte IV per encryption ensures different ciphertexts for same plaintext
- 128-bit GCM authentication tag prevents tampering
Note: While encrypted storage is more secure than plaintext, environment variables remain the most secure option for production/CI/CD as they never touch disk.
Required Security Measures:
-
Always use HTTPS (not HTTP) for Nexus URLs
# Good nexus.url=https://nexus.example.com # Bad - credentials sent in cleartext! nexus.url=http://nexus.example.com -
Protect your credentials file:
chmod 600 ~/.flossware/nexus/nexus.properties -
Use Nexus user tokens instead of passwords:
- Nexus UI → User → Profile → User Token
- Use the generated token as your password
-
For automation/CI/CD, use environment variables:
export NEXUS_URL="https://nexus.example.com" export NEXUS_USER="your-username" export NEXUS_PASSWORD="your-token" -
Never commit credentials to version control:
# Add to .gitignore .flossware/ nexus.properties
All Platforms Credential Encryption:
- Desktop (Java): Passwords encrypted with AES-256-GCM (v1.30+), machine-specific key derivation
- Android: Credentials encrypted with AES256_GCM via EncryptedSharedPreferences
- iOS/macOS: Credentials encrypted with AES-256 hardware-backed Keychain
- ✅ Always test deletions with
--dry-runfirst - ✅ Use dedicated Nexus users with minimum required permissions
- ✅ Rotate credentials regularly
- ✅ Review Nexus audit logs periodically
- ✅ Keep JNexus and Java updated with latest security patches
- ❌ Never use admin credentials for automated cleanup
- ❌ Never commit credentials to version control
- ❌ Never disable HTTPS certificate validation
If you discover a security vulnerability, please DO NOT open a public issue.
Email: sfloess@redhat.com
See SECURITY.md for complete security documentation.
Licensed under the Apache License 2.0. See LICENSE file for details.
Contributions are welcome! Please submit pull requests or open issues on GitHub.
See CONTRIBUTING.md for development guidelines.