A lightweight, high-performance, color-coded Windows Batch utility designed to dynamically discover, switch, download, update, and clean up Java Development Kit (JDK) environments without system bloat.
- Zero Dependencies (100% Native Windows): Unlike SDKMAN or similar Unix-ports that require heavy POSIX subsystems (WSL, MSYS2, Git Bash,
curl,zip), this utility is built entirely on native Windows APIs. It leverages pure Batch and embedded.NETFramework endpoints for networking, zip extraction, and SHA256 cryptography to run instantly out-of-the-box on any Windows 10/11 machine. - Dynamic Vendor Architecture: Menus are dynamically grouped and filtered by vendor (Oracle, Adoptium, GraalVM, Corretto, Zulu, Microsoft) to keep your workspace clean and organized.
- Intelligent Background Sorting: Features a built-in, stable bubble-sort algorithm that organizes all discovered JDKs by their major version in descending order, ensuring your newest installations are always at the top of the list.
- Semantic Target Routing: Speak to the tool in human terms. Automatically jump to or install the latest available JDK using targets like
jvm latestorjvm lts. The engine queries the Adoptium API at runtime to dynamically resolve the true latest feature release and LTS version numbers, so you never have to hardcode them. - ARM64 / AArch64 Auto-Detection: Automatically detects your CPU architecture at startup (
x64vsARM64) and routes all vendor API queries to the correct architecture-specific download endpoint. Zero configuration needed β it just works on both Intel/AMD and ARM Windows machines. - Dual-Architecture Core (UAC-Free vs Registry): Toggle seamlessly between lightning-fast Symlink Mode (bypasses UAC completely using a Directory Junction at
%USERPROFILE%\.jvm\current) and legacy Registry Mode (auto-elevating background scripts to update systemHKLMenvironment variables) based on your system compatibility needs. - Directory-based Auto-Switching (.java-version & .sdkmanrc): Instantly switch to a project's required JDK version by simply running
jvminside any directory containing a.java-versionor SDKMAN.sdkmanrcfile. The tool parses the file and seamlessly swaps your environment in the background. Unlike SDKMAN which only stores static versions, our.java-versionengine is incredibly advanced: it natively supports parsing full CLI flags directly from the file (e.g.,21 --vendor adoptium --legacy), allowing you to lock specific vendors or architecture modes on a strict per-project basis. And if you're collaborating with SDKMAN users on macOS/Linux, JVM will happily hijack their.sdkmanrcfiles on Windows and map their vendor strings (-tem,-amzn, etc.) directly to your native JDKs. - Global Command & Shell Hooks: Features a built-in Settings menu that dynamically injects the
jvmcommand into your system PATH, and can optionally install a native PowerShell Profile Hook to enable true, isolated--sessionsupport across multiple terminal tabs. - Advanced CLI Quick-Switching: Supports intelligent argument parsing to bypass the UI entirely. If multiple vendors are installed for the same JDK version, it safely pauses to ask you which vendor you want to switch to, which can be bypassed on the fly with the
--vendorflag. - Multi-Vendor API Auto-Downloader: Connects directly to official vendor APIs (Oracle, GitHub for GraalVM, Adoptium v3, Azul, etc.) via a transparent, isolated PowerShell instance to dynamically resolve, download, and extract modern JDK versions.
- Enterprise-Grade Security: Enforces strict SHA256 checksum verification across all remote download pathways using native
.NETCryptography APIs. Validates payload integrity against official vendor signature mirrors before extraction, protecting against MITM attacks or corrupted binaries. - Inline Multi-Vendor Update Checker: Dynamically generates and executes a self-contained PowerShell update script at runtime to query all six vendor APIs (Oracle, Adoptium, GraalVM, Corretto, Zulu, Microsoft) for newer builds. Compares
SEMANTIC_VERSIONandJAVA_VERSIONstrings from the localreleasefile against live API responses, with automatic-LTSsuffix normalization for Adoptium. Oracle uses a legacyHEAD-request date comparison againstdownload.oracle.comfor maximum reliability. - Offline-Aware Error Handling: All network operations (downloads, update checks, API queries) are wrapped in structured error boundaries. If you are offline or an API is unreachable, the tool displays a clean
[ ERROR ] Network connection failed. You appear to be offline.message with a[ DETAIL ]trace instead of crashing with raw exception dumps. - Dynamic Environment Switching: Atomically updates
JAVA_HOMEand your user/systemPATHglobally while cleanly updating the environment variables of your active terminal session without spawning double paths. - The "Phantom Path" Killer: Unlike other version managers that passively append to your PATH (which Windows often ignores if a hardcoded shortcut exists), JVM actively hunts down and scrubs rogue, hardcoded Oracle shortcuts (e.g.,
Common Files\Oracle\Java\javapath) that MSIs forcefully inject into the front of yourPATH, ensuring your selectedJAVA_HOMEis always respected. - Bring Your Own JDK (BYO-JDK): Have a custom JDK build or a GraalVM native-image compiler installed manually? Use
jvm link <path> [name]to register it, and it will instantly integrate into the dynamic UI and CLI routing alongside your auto-downloaded JDKs. - Instant Menu Navigation: Uses a smart
NEEDS_RESCANcaching architecture to guarantee zero-latency navigation when moving back and forth between interactive submenus. - Built-in Self-Updater with Integrity Verification: Run
jvm version(or-v) to trigger the intelligent semantic versioning engine. It securely mathematically compares your local build against the remote GitHubmainbranch (e.g.20260830.10>20260830.2). If an update is available,jvm self-updatewill verify the downloaded file contains a valid:: END OF SCRIPTsentinel before atomic-swapping the core script, protecting against truncated or corrupted downloads.
Windows Directory Junctions (Symlinks) provide a massive speed and workflow improvement because they allow the script to instantly swap your Java version without ever needing Administrator privileges (UAC). By routing your User PATH to a single junction (%USERPROFILE%\.jvm\current), 99% of modern tools (Gradle, Maven, IDEs) can natively resolve the path entirely in the background.
However, some ultra-legacy enterprise Java applications or obscure classloaders perform strict canonical path resolution that can occasionally fail to traverse Windows Directory Junctions. To ensure 100% unbreakable compatibility for all workflows, we built a Dual-Architecture Core.
By navigating to the Settings menu, users can freely toggle between:
- [Symlink Mode]: The default, blazing-fast, UAC-Free approach that dynamically updates a junction pointer in your user directory.
- [Registry Mode]: The classic, battle-tested legacy approach. The script generates an elevated background wrapper to forcefully update the system's absolute
HKLMpaths in the Windows Registry (requires a UAC prompt on switch).
Warning
Architecture Conflicts: Windows evaluates Machine (HKLM) paths before User (HKCU) paths. If you use Registry Mode (which writes to the Machine level) and later switch back to Symlink Mode (which writes to the User level), the old Machine path would normally stubbornly override your new Symlink! To prevent this, toggling back to Symlink Mode inside the Settings Menu will now automatically scrub the legacy Machine pollution for you. (Note: If you manually bypass the menu using --legacy and --symlink CLI flags and experience an override, simply run jvm clear to wipe the slate).
You can even override your global setting dynamically on a per-command basis using the --symlink or --legacy CLI flags (e.g., jvm 21 --legacy).
Despite being nearly 100 KB in size, the jvm.bat engine is mathematically optimized to bypass the notorious bottlenecks and memory leaks of standard Windows Batch scripts:
- Zero Label-Scanning Latency: Standard scripts suffer severe performance penalties when using
call :labelfor high-frequency loops (becausecmd.exesearches the file linearly from top to bottom). Our heaviest logic, such as the multi-vendor Semantic Bubble Sort algorithm, is written as a strictly in-memory inline array swapper, ensuring instantaneous sorting regardless of file size. - Leak-Proof
SETLOCALBoundaries: We completely sidestepped the dreadedMaximum setlocal recursion level reachedcrash. Every single utility function explicitly pops its scope boundary back to the system using terminalexit /bunwinds, guaranteeing zero memory leaks across thousands of loop iterations. - Bulletproof Escape Boundaries: We utilize hexadecimal parsing and dedicated PowerShell payloads (
$null) to ensure thatcmd.exenever accidentally swallows caret characters (^), exclamation marks (!), or spaces when resolving UAC-elevated registry wrappers in the background. - Quote-Safe PATH Export: All
for /floops that transfer variables acrosssetlocal/endlocalboundaries use a double-quote encapsulation strategy (""!VAR!""with%%~Astripping) to guarantee safe handling ofPATHstrings containing embedded double-quotes β a common Windows scenario that normally causescmd.exeto misinterpret path segments as filenames.
- OS: Windows 10 or Windows 11
- Privileges: Standard User (UAC bypass is enabled by default via Symlink Architecture). Administrator rights are only requested if you explicitly switch to legacy Registry Mode, or during global system installations.
- Launch
jvm.batto open the interactive menu, or run it from any terminal. - Navigate to Settings (Global Command & Setup) to install the
jvmglobal command. - Once installed globally, you can use the following commands from anywhere:
Instantly update your JAVA_HOME and system PATH without opening menus. If there are duplicates, you will be prompted to pick a vendor.
jvm 21β Switch to JDK 21 (Globally).jvm 21 --sessionβ Switch to JDK 21 locally for the current terminal only (requires the PowerShell Profile hook to be installed).jvm 21 --symlinkβ Force the switch to use Symlink Mode (UAC-Free) for this command, ignoring your saved defaults.jvm 21 --legacyβ Force the switch to use legacy Registry Mode (requests UAC) for this command, ignoring your saved defaults.jvm 21 --vendor adoptiumβ Override priority and explicitly switch to Adoptium's JDK 21.jvm latestβ Dynamically switch to the absolute highest installed JDK version.jvm ltsβ Dynamically switch to the highest installed LTS version.jvmβ If run inside a directory containing a.java-versionfile, it will silently parse it and auto-switch to that version locally for the current terminal only. If no.java-versionfile exists, it opens the main interactive terminal UI menu. (Note: Your.java-versionfile can also contain CLI flags, such as21 --vendor adoptium --legacy. Make sure the version and flags are all on a single line. Architecture flags like--legacywill only take effect if you runjvm --global).jvm --globalβ Parses the.java-versionfile and forces the version switch to apply globally to your system registry.
jvm installβ Opens the fully interactive Installation Wizard UI.jvm install 21β Initiates the installation of JDK 21 (pauses to prompt you for your preferred Vendor).jvm install 21 --vendor oracleβ Bypasses all prompts to silently download and install Oracle JDK 21.jvm install ltsβ Prompts you to pick an LTS version (e.g., 17, 21, 25) and then prompts you for your preferred Vendor before installing.jvm install lts --latestβ Skips the version prompt (locks onto the highest available LTS) but still pauses to prompt you for a Vendor.jvm install lts --latest --vendor oracleβ 100% automated headless installation of the absolute newest Oracle LTS version (bypasses all menus).jvm install 17 --vendor oracle -yβ (or--yes) Aggressively bypasses any remaining interactive safety warnings (like Oracle's legacy version caps or "already installed" warnings) for 100% uninterrupted CI/CD automation.
jvm updateβ Opens the dynamic, vendor-sorted Updater menu UI.jvm update --allβ Silently checks and automatically patches all installed JDKs across all vendors.jvm update --all --vendor oracleβ Silently checks and automatically patches only your installed Oracle JDKs (the--allflag is optional here).jvm uninstallβ Opens the dynamic, vendor-sorted Uninstaller menu UI.jvm uninstall 21β Headless uninstallation for JDK 21. If multiple vendors are found for the same version, it safely pauses to ask you which vendor you want to remove.jvm uninstall 21 --vendor oracleβ 100% headless uninstallation specifically targeting the Oracle vendor (bypasses all prompts).
jvm listβ Lists all installed JDKs with their version, vendor, path, and highlights the currently[ACTIVE]one.jvm envβ Displays the currentJAVA_HOMEenvironment variable.jvm clearβ Instantly wipesJAVA_HOMEand purges Java from your PATH.jvm link <path> [name]β Manually link an existing, custom JDK directory into the manager so you can easily switch to it (e.g.,jvm link C:\my-custom-jdk my-jdk). Linked JDKs automatically integrate into the interactive UI under the "Custom (Local Links)" vendor category.jvm unlink <name>β Removes a custom linked JDK.jvm versionβ Displays your currentjvm.batbuild number and compares it against the latest release on GitHub to check for updates.jvm self-updateβ Automatically downloads and atomic-swaps the corejvm.batscript if a newer version is available on GitHub.jvm <semantic-alias>β Switch to a JDK using intelligent aliases instead of exact version numbers. Examples:jvm latest(Switches to the absolute newest JDK installed)jvm lts(Switches to the newest Long-Term Support version installed)jvm 21(Switches to the newest minor build of Java 21)jvm lts --vendor corretto(Switches to the newest Amazon Corretto LTS version)
The utility uses native ANSI terminal color formatting to protect system stability:
- πΉ Cyan
[ ACTION ]/[ INFO ]β Indicates system operations, network lookups, and diagnostic information. Version numbers are highlighted in cyan for rapid scanning. - πΈ Yellow
[ WARNING ]/[ UPDATE ]β Points out non-critical issues, available patches, or destructive prompts. - πΊ Red
[ ERROR ]β Warns of network failures, blocked file permissions, or locked folders. - πΉ Green
[ACTIVE]/[ OK ]β Highlights the JDK entry currently actively powering your terminal environment, or signifies a successful operation. - β½ Gray β Mutes absolute file paths to reduce terminal clutter.
To prevent catastrophic accidental deletions on local filesystems, all critical prompts obey standard developer conventions:
- The uninstaller and update prompts use a strict
(y/N)validation. - Pressing Enter or typing anything other than an explicit
Y/yacts as an immediate safe abort. - Custom loops trap premature
Ctrl+Ccommands gracefully, and auto-close countdowns can be interrupted with any keystroke.
- v0.6.0 (Latest): Massive architecture overhaul. Migrated core architecture to use Directory Junctions (
%USERPROFILE%\.jvm\current), enabling 100% UAC-free, instantaneous version switching that dynamically syncs across all open terminal windows. Built a Dual-Architecture engine, allowing users to seamlessly toggle between the new Symlink Mode and the legacy Registry Mode directly from the Settings Menu. Re-engineered legacy Registry Mode to utilize background PowerShell wrappers, fixing a major historical bug where switching versions would fail silently for non-Admin users. Introduced dynamic Vendor grouping (Oracle, Adoptium, GraalVM, Corretto, Zulu, Microsoft) across all menus. Built an optimized, strictly in-memory Bubble Sort algorithm to organize JDKs by newest version. Added.java-versionand.sdkmanrcdirectory-based auto-switching (defaults to session-mode isolation) with an explicit--globalCLI override flag, support for passing full CLI flags directly inside.java-version, and a native.sdkmanrcparser to dynamically hijack cross-platform SDKMAN workflows. Implemented enterprise-grade SHA256 checksum verification for all JDK downloads using native.NETCryptography APIs to protect against corrupted payloads. Added semantic CLI routing (jvm latest,jvm lts) and flag overrides (--symlink,--legacy,--vendor,--latest,-y). Added ARM64/AArch64 hardware auto-detection, routing all vendor API queries to architecture-specific download endpoints. Built a dynamicFetchLatestVersionsresolver that queries the Adoptium API at runtime to resolve the true latest feature release and LTS version numbers, eliminating hardcoded version constants. Re-engineered theUpdateCheckeras a fully self-contained inline PowerShell script generated at runtime for all six vendors, removing all external.ps1file dependencies. Added structured offline-aware error handling across all network operations with clean[ ERROR ]/[ DETAIL ]output instead of raw exception dumps. Eliminated hardcoded UI prioritization in favor of interactive vendor-selection prompts. Restored native extraction progress bars (with a forced final 100% frame to fix a rounding edge case) and stabilized interactive installer UI layout. Improved navigation speed via a smart cachingNEEDS_RESCANarchitecture. Fixed cross-architecture registry conflicts between User and Machine environment variables. Fixed UAC elevation deadlocks, delayed expansion engine parsing bugs affecting the--globalflag and exclamation marks, character-encoding path bugs for user profiles, and critical bugs that corrupted paths containing exclamation marks (!). Fixed Adoptium update checks incorrectly reporting newer builds due to a-LTSsuffix mismatch. Fixed Oracle update checks crashing with'$' is not recognizedby switching the PowerShell payload to pipe-safe string concatenation. Replaced deprecatedwmicenvironment queries with directreg querycalls for forward compatibility with Windows 11. Hardened allfor /fvariable export loops with double-quote encapsulation to preventcmd.exefrom misinterpretingPATHstrings containing embedded quotes as file lists. Added conditionalrmdirguard to prevent extracted files from being destroyed on move failure. Added a:: END OF SCRIPTsentinel integrity check to the self-updater to reject truncated or corrupted downloads. Aligned all UI tags to a strict 10-character padded format. Built a seamless semantic self-updater engine (jvm version,jvm self-update) that securely compares build numbers using the native.NET[version]class before automatically downloading and atomic-swapping the core script. - v0.5.0: Introduced CLI Quick-Switching (
jvm <version>) for silent background execution. Added Global Command Installer (Settings menu). Overhauled UI with strict ANSI color hierarchy, path muting, and interruptible auto-close countdowns. Hardened UAC elevation and menu scanning against Windows PATH corruption bugs. - v0.4.0: Re-engineered dynamic auto-scanner supporting developer toolkits (Scoop, Gradle, IntelliJ), fast release-file parsing, and a massive architectural UI overhaul for robust sub-menu navigation.
- v0.3.0: Relicensed the project to the GNU Affero General Public License v3.0 (AGPL-3.0).
- v0.2.0: Added intelligent update checker (via HTTP
HEADrequests), "Update All" bulk-patching, and automated directory hot-swapping. - v0.1.1: Patched
PATHvariable corruption bugs and improved delayed-expansion safety protocols during active session switching. - v0.1.0: Initial Release.
Copyright Β© 2026 DiamTek / AlexΓ©y Shishkin.
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See the LICENSE file for details.
Note: Oracle JDK downloads triggered by this tool are subject to the Oracle No-Fee Terms and Conditions (NFTC).