@stescobedo9205/jwmv
v1.0.2
Published
A fast, lightweight CLI tool to install, manage, and switch between multiple Java (JDK) versions on Windows.
Maintainers
Readme
jwmv — Java Version Manager for Windows
A fast, lightweight CLI tool to install, manage, and switch between multiple Java (JDK) versions on Windows. Built with .NET 8, inspired by tools like SDKMAN! and nvm.
Features
- Install any JDK — Temurin, Zulu, GraalVM, Microsoft, Corretto, Liberica, SAP, Oracle and more via Foojay Disco API
- Switch versions instantly — per-session, per-project (
.jwmvrc), or set a persistent default - Shell integration — PowerShell profile bootstrap for automatic version switching
- Self-update — update jwmv itself from GitHub Releases
- Diagnostics —
doctorcommand detects PATH conflicts and misconfigurations - Single-file executable — no runtime dependencies, just download and run
- Windows x64 & ARM64 support
Installation
winget (recommended)
winget install stescobedo92.jwmvnpm
npm install -g @stescobedo9205/jwmvDownloads the native binary for your architecture automatically. No .NET runtime needed.
.NET global tool
dotnet tool install -g jwmvRequires the .NET 8 runtime.
Download from GitHub Releases
# Download the latest release for your architecture
# https://github.com/stescobedo92/jwmv/releases
# Extract and place jwmv.exe somewhere in your PATH, for example:
Expand-Archive jwmv-win-x64.zip -DestinationPath "$HOME\.jwmv\bin"
# Add to PATH (run once)
[Environment]::SetEnvironmentVariable(
"Path",
"$HOME\.jwmv\bin;" + [Environment]::GetEnvironmentVariable("Path", "User"),
"User"
)Quick Start
# See what's available
jwmv list
# Install Java 21 (Temurin) and set it as default
jwmv install 21-tem --default
# Verify
jwmv current
java -version
# Install another version
jwmv install 17-zulu
# Switch for this session
jwmv use 17-zuluCommands
jwmv list [filter]
List available JDK distributions from the Foojay catalog.
# List all available JDKs
jwmv list
# Filter by major version
jwmv list 21
# Filter by distribution
jwmv list tem
# Filter by version + distribution
jwmv list 17-zulu
# Force catalog refresh
jwmv list --refreshAliases: ls
| Option | Description |
|-----------------|------------------------------------|
| [filter] | Optional version/distribution filter |
| -r, --refresh | Force refresh the catalog cache |
jwmv install [identifier]
Install a JDK version. Runs interactively if no identifier is provided.
# Interactive mode — prompts for filter and selection
jwmv install
# Install a specific version
jwmv install 21-tem
# Install and set as the default JAVA_HOME
jwmv install 21.0.4-tem --default
# Install with forced catalog refresh
jwmv install 17-zulu --refresh| Option | Description |
|-----------------|--------------------------------------------|
| [identifier] | Version identifier (e.g. 21-tem, 17-zulu) |
| -d, --default | Set as default JAVA_HOME after install |
| -r, --refresh | Force refresh the catalog before install |
Identifier format: <version>-<distribution> where distribution is a short alias:
| Alias | Distribution |
|-----------|---------------------|
| tem | Eclipse Temurin |
| zulu | Azul Zulu |
| ms | Microsoft OpenJDK |
| graalvm | GraalVM Community |
| cor | Amazon Corretto |
| lib | Liberica |
| sap | SAP Machine |
| ojdk | Oracle OpenJDK |
| oracle | Oracle JDK |
jwmv uninstall [identifier]
Remove an installed JDK version.
# Interactive selection
jwmv uninstall
# Remove a specific version
jwmv uninstall 17-zuluAliases: remove, delete, rm
jwmv installed
List all locally installed JDK versions.
jwmv installedAliases: local
jwmv use <identifier>
Activate a JDK for the current shell session. Does not modify the persistent default.
# Switch to Java 17 for this session
jwmv use 17-zulu
# Specify shell explicitly
jwmv use 21-tem --shell powershellNote: When running as an executable,
useemits a PowerShell script to stdout. For seamless switching, set up shell integration.
| Option | Description |
|------------------|-------------------------------|
| <identifier> | Version to activate (required) |
| --shell <SHELL> | Target shell (default: powershell) |
jwmv default <identifier>
Set the persistent default JAVA_HOME for all new shell sessions.
# Set Java 21 Temurin as the system-wide default
jwmv default 21-temThis updates the Windows User environment variables (JAVA_HOME, PATH) and broadcasts the change so new terminals pick it up immediately.
jwmv current
Show the currently active Java version and how it was resolved.
jwmv currentOutput shows:
- Active version alias
- Resolution source: Default, Session, or Project
- Resolved
JAVA_HOMEandbinpaths - Project
.jwmvrcpath (if applicable)
jwmv home [identifier]
Print the JAVA_HOME path for a version. Useful for scripting.
# Current JAVA_HOME
jwmv home
# JAVA_HOME for a specific version
jwmv home 17-zulu
# Use in scripts
$env:JAVA_HOME = $(jwmv home 21-tem)jwmv upgrade [identifier]
Upgrade installed JDK(s) to the latest patch in the same major/vendor track.
# Upgrade a specific installation
jwmv upgrade 21-tem
# Upgrade all installed versions
jwmv upgradejwmv update
Refresh the local catalog cache from the Foojay API.
jwmv updateThe catalog is cached locally and auto-refreshes every 6 hours (configurable). Use this to force an immediate refresh.
jwmv doctor
Run diagnostics to detect common issues.
jwmv doctorChecks for:
JAVA_HOMEcorrectnessPATHconflicts (e.g. system Java taking precedence)- PowerShell profile integration status
java.exeresolution viawhere.exe
jwmv config
Display the current jwmv configuration.
jwmv configShows: root directory, config file path, preferred distribution, catalog refresh interval, auto-env setting, default shell, and self-update repository.
jwmv integrate
Install the PowerShell profile hook for automatic version switching.
# Auto-detect profile
jwmv integrate
# Specify shell
jwmv integrate --shell powershell
# Custom profile path
jwmv integrate --profile "C:\Users\me\Documents\PowerShell\Microsoft.PowerShell_profile.ps1"| Option | Description |
|---------------------|---------------------------------|
| --shell <SHELL> | Target shell (default: powershell) |
| --profile <PATH> | Custom profile file path |
jwmv env
Print environment activation scripts or show project configuration.
# Show project .jwmvrc
jwmv env
# Emit initialization script
jwmv env --init
# Emit for a specific directory
jwmv env --cwd ./my-project| Option | Description |
|------------------|-----------------------------------------|
| --shell <SHELL> | Target shell |
| --cwd <PATH> | Working directory to scan for .jwmvrc |
| --init | Emit shell initialization script |
jwmv flush
Clear cached files selectively.
# Clear downloaded archives
jwmv flush --archives
# Clear temporary files
jwmv flush --temp
# Clear catalog cache
jwmv flush --catalog
# Clear everything
jwmv flush --archives --temp --catalog| Option | Description |
|---------------|----------------------------------|
| --archives | Delete downloaded ZIP archives |
| --temp | Delete temporary extraction files |
| --catalog | Delete the catalog cache |
jwmv selfupdate
Update jwmv itself from GitHub Releases.
# Check for updates
jwmv selfupdate --check
# Apply update
jwmv selfupdate
# Skip confirmation
jwmv selfupdate --yes
# Force reinstall current version
jwmv selfupdate --force
# Update and restart
jwmv selfupdate --restart
# Use a different repository
jwmv selfupdate --repository owner/repoAliases: self-update
| Option | Description |
|---------------------------|------------------------------------------|
| -c, --check | Only check, don't apply |
| -f, --force | Force update even if same version |
| -y, --yes | Skip confirmation prompt |
| --restart | Restart jwmv after update |
| -r, --repository <REPO> | GitHub owner/repo for releases |
| -t, --tag <TAG> | Specific release tag to install |
Shell Integration
jwmv can automatically switch Java versions when you cd into a project with a .jwmvrc file.
Setup
jwmv integrateThis adds a managed block to your PowerShell profile ($PROFILE) that bootstraps jwmv on every new terminal session. The integration:
- Reads the current or project-specific Java version
- Sets
JAVA_HOMEandPATHautomatically - Switches versions seamlessly as you navigate between projects
Manual integration
Add this to your PowerShell profile ($PROFILE):
# >>> jwmv initialize >>>
$jwmvInit = & jwmv env --init --shell powershell 2>$null
if ($jwmvInit) { $jwmvInit | Invoke-Expression }
# <<< jwmv initialize <<<Per-Project Java Version
Create a .jwmvrc file in your project root:
21-temWhen shell integration is active, jwmv automatically activates this version when you enter the directory. The resolution order is:
- Session — set via
jwmv use - Project — from
.jwmvrc(walks up the directory tree) - Default — set via
jwmv default
Configuration
jwmv stores its data under ~/.jwmv/:
~/.jwmv/
├── config.json # User configuration
├── candidates/
│ └── java/ # Installed JDKs
├── archives/ # Downloaded ZIP files
├── tmp/ # Temporary extraction files
└── var/
├── catalog.json # Cached Foojay catalog
└── manifests/
└── java/ # Installation metadata (one JSON per version)config.json
{
"preferredDistributionAlias": "tem",
"catalogRefreshHours": 6,
"autoEnvEnabled": true,
"defaultShell": "powershell",
"defaultJavaAlias": "21-tem",
"selfUpdateRepository": "stescobedo92/jwmv"
}| Key | Default | Description |
|-----------------------------|----------------|----------------------------------------------|
| preferredDistributionAlias | "tem" | Default distribution when not specified |
| catalogRefreshHours | 6 | Hours before catalog auto-refreshes |
| autoEnvEnabled | true | Enable .jwmvrc auto-switching |
| defaultShell | "powershell" | Shell for script generation |
| defaultJavaAlias | — | Persistent default Java version |
| selfUpdateRepository | — | GitHub owner/repo for self-update |
Usage Examples
Managing a multi-project workflow
# Project A needs Java 17
cd C:\Projects\legacy-app
echo "17-cor" > .jwmvrc
# Project B needs Java 21
cd C:\Projects\modern-api
echo "21-tem" > .jwmvrc
# Install both versions
jwmv install 17-cor
jwmv install 21-tem --default
# With shell integration, Java switches automatically
cd C:\Projects\legacy-app
java -version # → Corretto 17
cd C:\Projects\modern-api
java -version # → Temurin 21Architecture
Jwmv.Cli → Spectre.Console CLI commands and DI setup
Jwmv.Core → Interfaces, models, utilities (no dependencies)
Jwmv.Infrastructure → Foojay API client, storage, Windows integration
Jwmv.Tests → XUnit testsThe project follows a clean architecture pattern with dependency inversion. All services are behind interfaces and injected via Microsoft.Extensions.DependencyInjection.
Building & Testing
# Restore
dotnet restore
# Build
dotnet build -c Release
# Test
dotnet test
# Publish single-file executable
dotnet publish src/Jwmv.Cli -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -p:EnableCompressionInSingleFile=trueLicense
This project is open source. See the repository for license details.
