JWMV Sergio Triana Escobedo
winget install --id=stescobedo92.JWMV -e A fast, lightweight CLI to install, manage, and switch between multiple Java (JDK) versions on Windows.
winget install --id=stescobedo92.JWMV -e A fast, lightweight CLI to install, manage, and switch between multiple Java (JDK) versions on 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.
.jwmvrc), or set a persistent defaultdoctor command detects PATH conflicts and misconfigurationswinget install stescobedo92.jwmv
npm install -g @stescobedo9205/jwmv
> Downloads the native binary for your architecture automatically. No .NET runtime needed.
dotnet tool install -g jwmv
> Requires the .NET 8 runtime.
# 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"
)
# 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-zulu
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 --refresh
Aliases: 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: - 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-zulu
Aliases: remove, delete, rm
jwmv installedList all locally installed JDK versions.
jwmv installed
Aliases: local
jwmv use 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 powershell
> Note: When running as an executable, use emits a PowerShell script to stdout. For seamless switching, set up shell integration.
| Option | Description |
|---|---|
| `` | Version to activate (required) |
--shell | Target shell (default: powershell) |
jwmv default Set the persistent default JAVA_HOME for all new shell sessions.
# Set Java 21 Temurin as the system-wide default
jwmv default 21-tem
This updates the Windows User environment variables (JAVA_HOME, PATH) and broadcasts the change so new terminals pick it up immediately.
jwmv currentShow the currently active Java version and how it was resolved.
jwmv current
Output shows:
JAVA_HOME and bin paths.jwmvrc path (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 upgrade
jwmv updateRefresh the local catalog cache from the Foojay API.
jwmv update
The catalog is cached locally and auto-refreshes every 6 hours (configurable). Use this to force an immediate refresh.
jwmv doctorRun diagnostics to detect common issues.
jwmv doctor
Checks for:
JAVA_HOME correctnessPATH conflicts (e.g. system Java taking precedence)java.exe resolution via where.exejwmv configDisplay the current jwmv configuration.
jwmv config
Shows: root directory, config file path, preferred distribution, catalog refresh interval, auto-env setting, default shell, and self-update repository.
jwmv integrateInstall 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 | Target shell (default: powershell) |
--profile | Custom profile file path |
jwmv envPrint 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 | Target shell |
--cwd | Working directory to scan for .jwmvrc |
--init | Emit shell initialization script |
jwmv flushClear 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 selfupdateUpdate 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/repo
Aliases: 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 | GitHub owner/repo for releases |
-t, --tag | Specific release tag to install |
jwmv can automatically switch Java versions when you cd into a project with a .jwmvrc file.
jwmv integrate
This adds a managed block to your PowerShell profile ($PROFILE) that bootstraps jwmv on every new terminal session. The integration:
JAVA_HOME and PATH automaticallyAdd this to your PowerShell profile ($PROFILE):
# >>> jwmv initialize >>>
$jwmvInit = & jwmv env --init --shell powershell 2>$null
if ($jwmvInit) { $jwmvInit | Invoke-Expression }
# <<< jwmv initialize <<<
Create a .jwmvrc file in your project root:
21-tem
When shell integration is active, jwmv automatically activates this version when you enter the directory. The resolution order is:
jwmv use.jwmvrc (walks up the directory tree)jwmv defaultjwmv 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 |
# Project A needs Java 17
cd ~\examples\legacy-app
echo "17-cor" > .jwmvrc
# Project B needs Java 21
cd ~\examples\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 ~\examples\legacy-app
java -version # → Corretto 17
cd ~\examples\modern-api
java -version # → Temurin 21
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 tests
The project follows a clean architecture pattern with dependency inversion. All services are behind interfaces and injected via Microsoft.Extensions.DependencyInjection.
This project is open source. See the repository for license details.