Skip to content

Latest commit

 

History

History
446 lines (347 loc) · 25.8 KB

INSTALLATION.md

File metadata and controls

446 lines (347 loc) · 25.8 KB

Installation


Getting started with the Java Version Manager for Windows takes less than 10 seconds. There are no external dependencies required.

🔍 Quick Jump


Standard Installation (PowerShell)

Open Windows PowerShell (you do not need Administrator privileges) and run the one-liner for your preferred channel:

🟢 Stable Channel (Official Releases — Recommended for production/workstations):

irm https://raw.githubusercontent.com/DiamTek/Java-Version-Manager-Windows/main/install.ps1 | iex

🟣 Nightly Channel (Cutting-Edge — Latest commits directly from main branch):

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/DiamTek/Java-Version-Manager-Windows/main/install.ps1))) -Channel Nightly

Or via explicit Invoke-WebRequest:

Invoke-WebRequest -Uri "https://raw.githubusercontent.com/DiamTek/Java-Version-Manager-Windows/main/install.ps1" -OutFile "$env:TEMP\install.ps1"; & "$env:TEMP\install.ps1"

Tip

Atomic Rollback & Resource Safety: install.ps1 snapshots existing installations to $batBackup = "$batPath.bak.<guid>.tmp". If companion file verification fails or an exception occurs, the overarching finally block atomically restores $batBackup back to $batPath, deletes all .stage.*.tmp files, releases COM objects, and leaves your workstation clean (CWE-460 / CWE-459).

Choosing Your Update Channel (Stable vs Nightly)

DiamTek JVM supports two distinct update channels to match your workflow:

  • 🟢 [Stable] Channel (Default / Recommended):

    • Targets official GitHub release tags (releases/latest).
    • Downloads are cryptographically verified against official SHA256SUMS.txt digests before execution.
    • Guarantees thoroughly vetted releases and complete changelogs.
    • Recommended for primary workstations, production environments, and enterprise fleets.
  • 🟣 [Nightly] Channel (Cutting-Edge):

    • Targets the latest commit on the main branch (HEAD).
    • Delivers unreleased features, immediate bug patches, and the newest vendor scrapers.
    • Allows previewing capabilities days or weeks before general release.
    • Recommended for contributors, beta testers, and power users.

Tip: You can switch between channels at any time after installation via jvm channel [stable|nightly] or via Option 4 in the interactive Settings menu (jvm -> Settings).

What this script does:

  1. It downloads the latest jvm.bat core engine and companion branding assets (icon.ico, icon.png) from the repository.
  2. It provisions the %LOCALAPPDATA%\DiamTek\JVM\bin and assets directory structure on your system.
  3. It securely writes the jvm.bat executable into that binary path.
  4. It dynamically injects the path into your PowerShell $PROFILE and standard Windows Registry PATH so the jvm command is available immediately across all shells, registering dynamic multi-invocation tab-completion (jvm, jvm.bat, .\jvm.bat).
  5. It registers a dedicated Windows Terminal Profile with custom branding, launching cmd.exe /c with closeOnExit: always so tabs close cleanly on exit.
  6. It creates a Start Menu application shortcut and automatically updates any pinned Taskbar shortcuts.
  7. It registers into Windows Settings ("Installed apps") with an accurate dynamic EstimatedSize footprint calculation.

Manual Installation

Warning

Downloading jvm.bat manually via a web browser can sometimes result in GitHub serving the file with UNIX line endings (LF) instead of Windows line endings (CRLF), or injecting hidden UTF-8 BOM characters. This can cause severe batch execution bugs (like the cho crash). The automated PowerShell installer above automatically sanitizes these artifacts.

If you prefer not to use the automated PowerShell script and understand the risks of manual text formatting, you can install the tool manually using the built-in UI:

  1. Clone or download the repository to your machine (ensure it retains CRLF line endings).
  2. Create a folder somewhere safe (e.g., C:\Tools\JVM).
  3. Move the jvm.bat file into that folder.
  4. Double-click jvm.bat or run it from a terminal to open the interactive menu.
  5. Navigate to Settings (3) -> Install Global Command (1).
  6. The script will dynamically inject its current folder into your Windows User PATH.
  7. Restart your terminal and type jvm.
  8. (Optional) To enable automatic real-time JAVA_HOME and PATH synchronization across PowerShell tabs without restarting terminal windows, configure the PowerShell wrapper hook:
    jvm hook
    (Or navigate to Settings (3) -> Install PowerShell Profile Hook (2)).

Verifying Your Installation (jvm doctor)

Once installed, run the built-in system health auditor to verify that storage roots, directory junction permissions, registry states, and shell hooks are configured properly:

jvm doctor

Local Script Installation (install.ps1)

If you download install.ps1 or download the repository .zip to install locally:

  1. Unblock the downloaded script(s): Windows tags files downloaded via web browsers with an NTFS Zone.Identifier stream. Unblock before running:

    # Unblock install.ps1 directly:
    Unblock-File .\install.ps1
    
    # Or unblock all files across an extracted zip:
    Get-ChildItem -Recurse | Unblock-File

    (Alternatively: Right-click install.ps1 → Properties → check Unblock → OK).

  2. Execute the local installer:

    .\install.ps1
    # Or with explicit execution policy bypass:
    powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1
    
    # Or for offline installation from a pre-packaged distro:
    powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 -Offline -DistroDir .\jvm-offline-distro

Package Managers

Winget

winget install DiamTek.JVM

Scoop (Official Bucket)

scoop bucket add diamtek https://github.com/DiamTek/scoop-bucket
scoop install jvm

Chocolatey

choco install jvm-windows

Note

The Chocolatey package installs official release binaries pinned to the Stable channel directly from GitHub Releases, guaranteeing unreleased development commits are never pulled into production environments. For packaging automation, nuspec details, and local testing instructions, see the Chocolatey Package Documentation.

Standalone MSI Installers (WiX Toolset v4)

Standalone, single-file Windows Installers are available for both x64 (Intel/AMD) and arm64 (Qualcomm Snapdragon / Windows on ARM):

  1. Download jvm-windows-1.0.1-x64.msi or jvm-windows-1.0.1-arm64.msi directly from the Releases page.
  2. Double-click the .msi file to run the graphical setup wizard.

Silent / Headless Installation (Command Line)

For enterprise automation, scripts, or unattended CI environments:

msiexec /i jvm-windows-1.0.1-x64.msi /qn /norestart

To enable verbose installation logging for diagnostics:

msiexec /i jvm-windows-1.0.1-x64.msi /qn /norestart /l*v "%TEMP%\jvm-install.log"

Enterprise & Silent IT Deployment (Intune, MECM, GPO)

DiamTek JVM is built with a standard per-user Windows Installer architecture (Scope="perUser"), making it ideal for self-service engineering workstations or managed enterprise fleet distribution without requiring local administrator rights.

🏢 Corporate Zero-Admin & Standard User Strategy (Zero IT Tickets)

In enterprise environments with strictly locked-down corporate laptops, developers do not possess local administrator (UAC) credentials:

  • The Traditional IT Pain Point: Standard software installations and JDK setups write to C:\Program Files and HKLM, necessitating an IT helpdesk ticket, security exception, or technician intervention for every routine Java or build tool update.
  • The Zero-Admin JVM Architecture: DiamTek JVM installs into the current user's local application store (%LOCALAPPDATA%\DiamTek\JVM) and modifies user environment variables (HKCU).
  • 0-UAC Version Switching: JDK version switching leverages NTFS Directory Junctions (%LOCALAPPDATA%\DiamTek\JVM\current), an unprivileged user-space operation requiring 0 UAC prompts. Developers switch between JDK 11, 17, 21, and modern build tools independently without filing IT tickets or compromising corporate endpoint security.

⚙️ Enterprise Endpoint Management Configuration Matrix

Deploy silently fleet-wide via Microsoft Intune, Microsoft Endpoint Configuration Manager (MECM / SCCM), or Active Directory Group Policy (GPO):

Setting Configuration Value
Install Command msiexec /i "jvm-windows-1.0.1-x64.msi" /qn /norestart
Uninstall Command msiexec /x "jvm-windows-1.0.1-x64.msi" /qn /norestart
Verbose Logging msiexec /i "jvm-windows-1.0.1-x64.msi" /qn /norestart /l*v "%TEMP%\jvm-install.log"
Install Behavior User (per-user context)
Device Restart No specific action (zero reboot required)
Detection Rule (Registry) Key: HKCU\Software\DiamTek\JVM
Value: installed
Data Type: Integer (DWORD)
Operator: Equals 1
Detection Rule (File) Path: %LOCALAPPDATA%\DiamTek\JVM\bin
File: jvm.bat
Return Codes 0 (Success), 1602 (User Canceled), 1603 (Fatal Error), 3010 (Reboot - Handled gracefully)

🔒 Corporate Proxies, SSL Inspection & Internal Artifact Repositories

Deploying inside corporate enterprise perimeters with deep packet inspection (Zscaler, Netskope, Palo Alto) or internal artifact repositories (Artifactory, Nexus):

  • WinINet & System Proxy Auto-Traversal: JVM's internal .NET networking stack automatically detects and routes through corporate system proxies configured in Windows Settings or deployed via PAC scripts.
  • CLI Proxy Variables: Standard environment variables are honored for terminal-level proxy overrides:
    $env:HTTP_PROXY = "http://proxy.corporate.com:8080"
    $env:HTTPS_PROXY = "http://proxy.corporate.com:8080"
  • Enterprise Root CA Trust: Unlike Unix utilities that require manual Java truststore (cacerts) imports, JVM validates TLS certificates against the native Windows Trusted Root Certification Authorities store. Corporate root certificates deployed via Intune or GPO are trusted automatically.
  • Configurable Corporate Mirrors: Route all remote artifact downloads through corporate artifact storage engines (Nexus, Artifactory, internal CDN mirrors):
    jvm config set mirror "https://artifactory.corporate.internal/artifactory/jvm-mirror"
  • Internal / Pre-Approved JDKs (jvm link): If enterprise policy restricts public Internet downloads, teams can stage pre-approved internal JDK builds to a corporate share or local directory and register them instantly:
    jvm link "C:\Corporate\Java\zulu-21-approved" zulu-21

📦 Air-Gapped & Offline Corporate Environments

For secure air-gapped workstations or offline development networks with zero external internet connectivity:

  1. Self-Contained Offline Distro Creation (Connected Host): On an internet-connected build station, generate a standalone offline distribution containing jvm.bat, build tools, pre-cached runtimes, and SHA-256 integrity digests:
    jvm distro create --out .\jvm-offline-distro
  2. Zero-Network Distro Provisioning (Air-Gapped Host): Transfer the directory and install JVM without any outbound network calls:
    powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 -Offline -DistroDir .\jvm-offline-distro
  3. Cache Export & Bundling on Bastion Host: Alternatively, export the central Content-Addressed Storage cache into a portable bundle:
    jvm cache export --bundle .\build-cache.jvmcache
  4. Offline Ingestion: Transfer and ingest the package directly into the target workstation's Content-Addressed cache:
    jvm cache import .\build-cache.jvmcache
  5. Zero-Network Runtime Installation: Execute true air-gapped installations with 0 outbound network requests:
    jvm install 21 --offline
    jvm install maven 3.9.9 --offline
  6. Standalone Pre-Extracted Runtimes: Alternatively, extract pre-packaged runtimes into C:\Program Files\Java\ and bind them via jvm link <path> <name>.

Building the MSI from Source

You can compile native, standalone MSIs locally using the WiX Toolset v4 build pipeline. For full architecture details, custom action hooks, and test suite specifications, see the WiX MSI Package Documentation.

Prerequisites:

Build Commands: Run the standalone build script from anywhere on your machine (compiles both x64 and arm64 by default):

# If downloaded from the web or git archive, unblock once:
Unblock-File .\packages\msi\build-msi.ps1

# Build both x64 and arm64 MSIs (works from any working directory):
powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\msi\build-msi.ps1

# Or target a specific architecture:
powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\msi\build-msi.ps1 -Arch x64
powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\msi\build-msi.ps1 -Arch arm64

# Optional: Apply Authenticode digital signatures during compilation
powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\msi\build-msi.ps1 -Arch all -CertificateThumbprint "A1B2C3D4E5F6..."

The resulting single-file installers are placed directly into packages\msi\ (or the current folder when running standalone).

Note

build-msi.ps1 is fully autonomous and path-agnostic. You can run it from within the cloned repository or execute it completely standalone (e.g., downloaded directly to your Downloads folder). If local source files, the .NET SDK, or the WiX CLI are not present, build-msi.ps1 automatically bootstraps a user-space .NET SDK, exports DOTNET_ROOT, retrieves repository assets into %TEMP%, and builds the single-file MSIs.

Automated Test & Verification Suites

DiamTek JVM provides two automated test suites to verify system integrity and security:

1. Adversarial Security & Error-Injection Suite (tests/Test-JvmSecurity.ps1)

An enterprise-grade test harness executing 327 automated test cases across 16 defensive suites covering 41 MITRE CWE classes (CWE-20 through CWE-918, including CWE-798) with a verified 10.0 / 10.0 scorecard. Continuously tested in CI across both Windows PowerShell 5.1 and PowerShell 7+ (Core):

# Run using modern PowerShell 7+ (Recommended):
pwsh -NoProfile -ExecutionPolicy Bypass -File .\tests\Test-JvmSecurity.ps1

# Or run using native Windows PowerShell 5.1:
powershell -NoProfile -ExecutionPolicy Bypass -File .\tests\Test-JvmSecurity.ps1

2. Automated MSI Synthetic Verification Suite (packages\msi\test-msi.ps1)

The MSI subsystem includes a fully autonomous, 21-point integration verification test suite (packages\msi\test-msi.ps1). It actively tests live operating system integration—including the Windows Installer service (msiexec), CLI bin/ directory hygiene (guaranteeing internal hook scripts are isolated from PATH), Start Menu application and uninstaller shortcuts indexed by Windows Search, Windows Terminal settings.json, PowerShell $PROFILE hook & tab completer, update channel initialization (channel.txt), Windows Registry PATH, live CLI subshell process execution (cmd.exe /c "jvm.bat --version"), and full uninstallation with zero filesystem residuals. It features deterministic resource disposal and an emergency msiexec.exe /x rollback in its outer finally block if interrupted mid-test (CWE-460).

Autonomous 4-Tier Resolution Engine

You can run test-msi.ps1 from any working directory on any Windows machine (even on a clean machine with no prior source code, Git, .NET, or WiX installed). The test runner resolves packages using a 4-tier fallback hierarchy:

  1. Local Pre-Built MSI: Discovers and tests jvm-windows-*-x64.msi if already present in packages\msi\ or current path.
  2. Local WiX Compiler: If the .msi is missing, executes build-msi.ps1 -Arch x64 to compile it from local source files (auto-detecting the version from jvm.bat).
  3. Published GitHub Release: If local build tools/source are not available, downloads the latest official jvm-windows-*-x64.msi directly from GitHub Releases.
  4. Remote Source Bootstrap: If the release binary is not yet published, downloads the latest repository source archive (main.zip) from GitHub, extracts to %TEMP%, automatically bootstraps a user-space .NET SDK and WiX CLI, compiles the MSI, and runs the test suite.
Command Examples:
# Unblock the file if downloaded via browser (clears Zone.Identifier):
Unblock-File .\packages\msi\test-msi.ps1

# 1. Run the test suite silently (standard headless CI mode):
powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\msi\test-msi.ps1

# 2. Display the native Windows Installer progress bar dialog on screen:
powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\msi\test-msi.ps1 -ShowUI

# 3. Test and keep JVM installed on your machine ready to use:
powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\msi\test-msi.ps1 -KeepInstalled

# 4. Combine flags to watch the progress dialog and keep it installed:
powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\msi\test-msi.ps1 -ShowUI -KeepInstalled

# 5. Test a specific custom MSI binary:
powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\msi\test-msi.ps1 -MsiPath "C:\Path\To\custom.msi"

Tip

Interactive Graphical Setup Wizard: By default, test-msi.ps1 runs in silent mode (/qn) or progress dialog mode (/qb with -ShowUI). To open the traditional full Windows Installer wizard window with Next / Install / Finish buttons, double-click packages\msi\jvm-windows-1.0.1-x64.msi directly in File Explorer or run:

msiexec /i .\packages\msi\jvm-windows-1.0.1-x64.msi

Verifying GitHub Build Provenance & Attestation

Every official release MSI package published to GitHub Releases is cryptographically signed and attested using GitHub's Artifact Attestations system (actions/attest-build-provenance), powered by Sigstore and in-toto specifications.

This provides cryptographic, tamper-proof proof that:

  • The binary was compiled inside the official DiamTek/Java-Version-Manager-Windows repository workflow runners.
  • The build was triggered from a specific, immutable Git commit SHA.
  • The binary has not been modified, trojaned, or altered since compilation.
How to Verify using GitHub CLI (gh):
# Verify the downloaded MSI installer:
gh attestation verify jvm-windows-1.0.1-x64.msi --repo DiamTek/Java-Version-Manager-Windows

When verified, the GitHub CLI confirms certificate authority validity against the OIDC token:

Loaded digest sha256:... for jvm-windows-1.0.1-x64.msi
Loaded 1 attestation from GitHub API with build provenance
The following policy criteria will be validated:
- Certificate issuer must match: https://token.actions.githubusercontent.com
- Source repository owner must match: DiamTek
- Source repository must match: DiamTek/Java-Version-Manager-Windows
Verification succeeded!

🪟 Windows Terminal Integration

During installation via install.ps1 or the official WiX MSI installer, DiamTek JVM automatically inspects your Windows Terminal settings across Stable, Preview, and Unpackaged installations (settings.json).

  • Dedicated Dropdown Profile: JVM registers a dedicated profile named "Java Version Manager" with a unique GUID ({b20650a4-4212-4d64-9edf-744e9285e2be}) and high-resolution branding icon.
  • Accessing via Terminal: In Windows Terminal, click the + (new tab) dropdown arrow and select Java Version Manager to launch the interactive TUI directly.
  • Clean Tab Exit: The profile is configured with closeOnExit: always. When you exit the interactive menu (press 0 or select Exit), the hosting shell process terminates cleanly, signaling Windows Terminal to automatically close the tab without lingering blank prompts.
  • Taskbar Integration: The installer places a Start Menu shortcut and updates pinned taskbar shortcuts targeting wt.exe -p "Java Version Manager" (with a graceful fallback to cmd.exe on machines without Windows Terminal).

Uninstallation

DiamTek Java Version Manager includes a dedicated, UAC-elevated deep uninstaller (uninstall.ps1) that completely scrubs the application, system PATH entries, PowerShell $PROFILE hooks, environment variables, ecosystem tool caches, Windows Terminal profiles, pinned taskbar shortcuts, and installed JDKs.

You can uninstall JVM through any of the following methods:

  1. Windows Settings (Installed Apps):
    • Open Windows Settings -> Apps -> Installed apps.
    • Locate DiamTek Java Version Manager and click Uninstall.
  2. Start Menu Shortcut:
    • Search "Uninstall Java Version Manager" in the Windows taskbar search box and press Enter.
  3. Interactive Terminal Interface:
    • Run jvm -> Navigate to Settings (3) -> Select Uninstall JVM Completely (6).
  4. Command Line (CLI):
    jvm self-uninstall
  5. Direct PowerShell Script:
    & "$env:LOCALAPPDATA\DiamTek\JVM\uninstall.ps1"
  6. Windows Installer (MSI) Silent Uninstallation:
    msiexec /x jvm-windows-1.0.1-x64.msi /qn

Troubleshooting & Windows Security

Downloaded Script Blocked or Not Digitally Signed (Zone.Identifier)

When downloading .ps1 scripts, archives, or installers via a web browser (Edge, Chrome, Firefox), Windows Attachment Manager marks the files with a hidden NTFS alternate data stream: Zone.Identifier (ZoneId=3 meaning "Internet").

Under the default Windows PowerShell execution policy (RemoteSigned), Windows requires all scripts downloaded from the Internet to possess a trusted Authenticode digital signature before allowing execution. Open-source scripts that are not signed with a commercial certificate will be blocked before line 1 with:

File ... cannot be loaded. The file ... is not digitally signed.

To resolve this, unblock the file(s) using any of these methods:

  1. PowerShell CLI (Recommended):

    # Unblock install.ps1 or uninstall.ps1 directly:
    Unblock-File .\install.ps1
    Unblock-File .\uninstall.ps1
    
    # Or unblock every file and script in an extracted folder recursively:
    Get-ChildItem -Recurse | Unblock-File
  2. File Explorer GUI:

    • Right-click the .ps1 (or .zip) file in File Explorer and select Properties.
    • At the bottom of the General tab, check the Unblock checkbox.
    • Click Apply and then OK.
  3. ExecutionPolicy Bypass: Launching PowerShell with -ExecutionPolicy Bypass instructs PowerShell to ignore both execution policies and zone restrictions for that session:

    powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1

PowerShell Execution Policy Errors

If the automated installer fails with a red error mentioning "cannot be loaded because running scripts is disabled on this system", your Windows machine has strict execution policies enabled.

To fix this, open your PowerShell terminal and run:

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

Press Y to confirm, then try running the installation one-liner again.


← Back to Documentation Overview