Skip to content

Instantly share code, notes, and snippets.

@CypherpunkSamurai
Created May 4, 2025 09:25
Show Gist options
  • Save CypherpunkSamurai/5250d0b5816a6bace497fc5c5e1caa3b to your computer and use it in GitHub Desktop.
Save CypherpunkSamurai/5250d0b5816a6bace497fc5c5e1caa3b to your computer and use it in GitHub Desktop.
JDK 22 Win Portable
# Script: Jdk22Portable.ps1
# Purpose: Download and set up portable JDK 22 from various vendors
# Author: Cypherpunk Samurai
# Version: 1.0
# -----------------------------------------
# This script creates a portable JDK setup
# by downloading JDK 22 from your preferred
# vendor and extracting it to a local folder
# -----------------------------------------
param (
[Parameter(Position=0, HelpMessage="JDK vendor index (1-4) or name (Oracle, OpenLogic, OpenJDK, BellSoft)")]
[string]$JdkVendor,
[Parameter(Position=1, HelpMessage="Target path for JDK installation")]
[string]$TargetPath,
[Parameter(Position=2, HelpMessage="Cache path for downloads")]
[string]$CachePath,
[Parameter(HelpMessage="Install without prompting (uses Oracle JDK by default)")]
[switch]$Quiet
)
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host " JDK 22 Portable Setup Utility" -ForegroundColor Cyan
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host ""
# Path Configs
$CACHE_PATH = if ($CachePath) { $CachePath } elseif ($env:PORTABLE_CACHE_PATH) { $env:PORTABLE_CACHE_PATH } else { Join-Path $PWD "Cache" }
$JDK_PATH = if ($TargetPath) { $TargetPath } elseif ($env:PORTABLE_JDK_PATH) { $env:PORTABLE_JDK_PATH } else { Join-Path $PWD "jdk/22/" }
$JDK_SHELL_LAUNCHER_PATH = if ($env:PORTABLE_JDK_SHELL_LAUNCHER_PATH) { $env:PORTABLE_JDK_SHELL_LAUNCHER_PATH } else { Join-Path $PWD "jdk/" }
# Create cache directory if it doesn't exist
if (-not (Test-Path $CACHE_PATH)) {
New-Item -Path $CACHE_PATH -ItemType Directory -Force | Out-Null
}
# Constants
$jdk_urls = @(
@{ Name = "Oracle JDK"; Url = "https://download.oracle.com/java/22/archive/jdk-22.0.2_windows-x64_bin.zip" },
@{ Name = "OpenLogic JDK"; Url = "https://builds.openlogic.com/downloadJDK/openlogic-openjdk/22.0.2+9/openlogic-openjdk-22.0.2+9-windows-x64.zip" },
@{ Name = "OpenJDK"; Url = "https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_windows-x64_bin.zip" },
@{ Name = "BellSoft JDK"; Url = "https://download.bell-sw.com/java/22.0.2+11/bellsoft-jdk22.0.2+11-windows-amd64.zip" }
)
# Get-PortableJDK function
function Get-PortableJDK {
param (
[Parameter(Mandatory=$true)]
[string]$Url,
[Parameter(Mandatory=$true)]
[string]$TargetFolder,
[Parameter(Mandatory=$true)]
[string]$CachePath
)
# Extract filename from URL
$fileName = Split-Path -Path $Url -Leaf
$downloadPath = Join-Path -Path $CachePath -ChildPath $fileName
# Download the file if it doesn't exist in cache
if (-not (Test-Path $downloadPath)) {
Write-Host "Downloading $fileName..." -ForegroundColor Yellow
try {
Invoke-WebRequest -Uri $Url -OutFile $downloadPath -UseBasicParsing
Write-Host "Download completed successfully." -ForegroundColor Green
} catch {
Write-Host "Failed to download JDK: $_" -ForegroundColor Red
return $false
}
} else {
Write-Host "Using cached $fileName" -ForegroundColor Green
}
# Create temporary extraction directory
$extractPath = Join-Path -Path $CachePath -ChildPath "extract_temp"
if (Test-Path $extractPath) {
Remove-Item -Path $extractPath -Recurse -Force
}
New-Item -Path $extractPath -ItemType Directory -Force | Out-Null
# Extract the zip file
Write-Host "Extracting JDK..." -ForegroundColor Yellow
try {
Expand-Archive -Path $downloadPath -DestinationPath $extractPath -Force
Write-Host "Extraction completed." -ForegroundColor Green
} catch {
Write-Host "Failed to extract JDK: $_" -ForegroundColor Red
return $false
}
# Find the JDK directory inside the extracted content (most JDKs have a subfolder)
$jdkFolders = Get-ChildItem -Path $extractPath -Directory
if ($jdkFolders.Count -eq 0) {
Write-Host "Error: No folders found in the extracted content." -ForegroundColor Red
return $false
}
# Create target directory if it doesn't exist
if (-not (Test-Path $TargetFolder)) {
New-Item -Path $TargetFolder -ItemType Directory -Force | Out-Null
}
# Move contents to target folder
Write-Host "Installing JDK to $TargetFolder..." -ForegroundColor Yellow
try {
# Move contents from the first directory in the extracted zip to the target
Get-ChildItem -Path $jdkFolders[0].FullName | ForEach-Object {
Copy-Item -Path $_.FullName -Destination $TargetFolder -Recurse -Force
}
Write-Host "JDK installed successfully." -ForegroundColor Green
} catch {
Write-Host "Failed to install JDK: $_" -ForegroundColor Red
return $false
}
# Clean up extraction directory
Write-Host "Cleaning up..." -ForegroundColor Yellow
Remove-Item -Path $extractPath -Recurse -Force
return $true
}
# Function to create a Java shell launcher script
function Create-JdkLauncherScript {
param (
[Parameter(Mandatory=$true)]
[string]$JdkPath,
[Parameter(Mandatory=$true)]
[string]$LauncherPath
)
# Create launcher directory if it doesn't exist
if (-not (Test-Path $LauncherPath)) {
New-Item -Path $LauncherPath -ItemType Directory -Force | Out-Null
}
$launcherScriptPath = Join-Path -Path $LauncherPath -ChildPath "Launch-JavaShell.ps1"
# Create the launcher script content
$scriptContent = @"
# Java Environment PowerShell Launcher
# Auto-generated by JDK Portable Setup
Write-Host "Java Development Environment" -ForegroundColor Green
Write-Host "--------------------------------" -ForegroundColor Green
# Set environment variables for this session
`$env:JAVA_HOME = "$JdkPath"
`$env:PATH = "`$env:JAVA_HOME\bin;`$env:PATH"
# Display Java version
Write-Host "Java Version:" -ForegroundColor Yellow
java -version
# Display available tools
Write-Host ""
Write-Host "Available Java Tools:" -ForegroundColor Yellow
Write-Host " - java : Run Java applications" -ForegroundColor Cyan
Write-Host " - javac : Java compiler" -ForegroundColor Cyan
Write-Host " - jar : Java archive tool" -ForegroundColor Cyan
Write-Host " - jshell : Java REPL environment" -ForegroundColor Cyan
# Create command prompt
Write-Host ""
Write-Host "Java environment is ready. You now have an interactive shell with Java tools." -ForegroundColor Green
Write-Host "Type 'exit' to close this window when finished." -ForegroundColor Yellow
# Set window title
`$host.UI.RawUI.WindowTitle = "Java Development Environment"
# Show the current directory prompt to make it clear this is an interactive shell
Write-Host ""
"@
# Write the script to file
Set-Content -Path $launcherScriptPath -Value $scriptContent -Force
# Check if PowerShell 7 is installed
$pwsh7Path = $null
# Look for pwsh.exe in common locations
$possiblePaths = @(
"C:\Program Files\PowerShell\7\pwsh.exe",
"${env:ProgramFiles}\PowerShell\7\pwsh.exe",
"${env:ProgramFiles(x86)}\PowerShell\7\pwsh.exe",
"C:\Program Files\PowerShell\pwsh.exe"
)
foreach ($path in $possiblePaths) {
if (Test-Path $path) {
$pwsh7Path = $path
break
}
}
# If not found in common locations, try to find it in PATH
if (-not $pwsh7Path) {
$pwsh7Path = Get-Command -Name "pwsh" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source
}
# Create a shortcut to the launcher script
$shortcutPath = Join-Path -Path $LauncherPath -ChildPath "Java Shell.lnk"
$WshShell = New-Object -ComObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($shortcutPath)
if ($pwsh7Path) {
Write-Host "PowerShell 7 detected, configuring launcher to use it." -ForegroundColor Green
$Shortcut.TargetPath = $pwsh7Path
} else {
Write-Host "PowerShell 7 not found, using Windows PowerShell." -ForegroundColor Yellow
$Shortcut.TargetPath = "powershell.exe"
}
$Shortcut.Arguments = "-NoExit -ExecutionPolicy Bypass -File `"$launcherScriptPath`""
$Shortcut.WorkingDirectory = $LauncherPath
$Shortcut.IconLocation = "$JdkPath\bin\java.exe,0"
$Shortcut.Save()
Write-Host "Launcher script created at: $launcherScriptPath" -ForegroundColor Green
Write-Host "Launcher shortcut created: $shortcutPath" -ForegroundColor Green
return $true
}
# Function to select JDK vendor based on input
function Select-JdkVendor {
param (
[string]$Input,
[switch]$QuietMode
)
# In quiet mode with no input, use Oracle JDK
if ($QuietMode -and -not $Input) {
Write-Host "Quiet mode: Using Oracle JDK by default" -ForegroundColor Yellow
return $jdk_urls[0] # Oracle JDK is at index 0
}
# If no input, prompt the user
if (-not $Input) {
Write-Host "Available JDK Vendors:" -ForegroundColor Yellow
for ($i = 0; $i -lt $jdk_urls.Count; $i++) {
Write-Host "$($i+1). $($jdk_urls[$i].Name)" -ForegroundColor Cyan
}
$selection = Read-Host "Select a JDK vendor (1-$($jdk_urls.Count))"
$vendorIndex = [int]$selection - 1
if ($vendorIndex -lt 0 -or $vendorIndex -ge $jdk_urls.Count) {
Write-Host "Invalid selection. Please select a number between 1 and $($jdk_urls.Count)." -ForegroundColor Red
return $null
}
return $jdk_urls[$vendorIndex]
}
# Check if input is a number
if ($Input -match '^\d+$') {
$vendorIndex = [int]$Input - 1
if ($vendorIndex -lt 0 -or $vendorIndex -ge $jdk_urls.Count) {
Write-Host "Invalid vendor index. Please select a number between 1 and $($jdk_urls.Count)." -ForegroundColor Red
return $null
}
return $jdk_urls[$vendorIndex]
}
# Check if input is a vendor name
$vendor = $jdk_urls | Where-Object { $_.Name -like "*$Input*" } | Select-Object -First 1
if ($vendor) {
return $vendor
}
Write-Host "Invalid vendor name. Available vendors: Oracle JDK, OpenLogic JDK, OpenJDK, BellSoft JDK" -ForegroundColor Red
return $null
}
# --------------------------------------------------------
# Main script execution starts here
# --------------------------------------------------------
# Show help if requested
if ($JdkVendor -eq "-h" -or $JdkVendor -eq "--help" -or $JdkVendor -eq "/?") {
Write-Host "Usage: ./Jdk22Portable.ps1 [JdkVendor] [TargetPath] [CachePath] [-Quiet]" -ForegroundColor Yellow
Write-Host ""
Write-Host "Parameters:" -ForegroundColor Yellow
Write-Host " JdkVendor - JDK vendor index (1-4) or name (Oracle, OpenLogic, OpenJDK, BellSoft)" -ForegroundColor Cyan
Write-Host " TargetPath - Target path for JDK installation (default: ./jdk/22)" -ForegroundColor Cyan
Write-Host " CachePath - Cache path for downloads (default: ./Cache)" -ForegroundColor Cyan
Write-Host " -Quiet - Install without prompting (uses Oracle JDK by default)" -ForegroundColor Cyan
Write-Host ""
Write-Host "Examples:" -ForegroundColor Yellow
Write-Host " ./Jdk22Portable.ps1 Oracle" -ForegroundColor Cyan
Write-Host " ./Jdk22Portable.ps1 2 D:\java\jdk22 D:\downloads\cache" -ForegroundColor Cyan
Write-Host " ./Jdk22Portable.ps1 -Quiet" -ForegroundColor Cyan
exit 0
}
# Select vendor
$selectedVendor = Select-JdkVendor -Input $JdkVendor -QuietMode:$Quiet
if (-not $selectedVendor) {
exit 1
}
# Show selected configuration
Write-Host "Selected Configuration:" -ForegroundColor Yellow
Write-Host " Vendor: $($selectedVendor.Name)" -ForegroundColor Cyan
Write-Host " Installation Path: $JDK_PATH" -ForegroundColor Cyan
Write-Host " Cache Path: $CACHE_PATH" -ForegroundColor Cyan
Write-Host ""
# Confirm installation (skip if in quiet mode)
if (-not $Quiet) {
$confirm = Read-Host "Proceed with installation? (Y/N)"
if ($confirm -ne "Y" -and $confirm -ne "y") {
Write-Host "Installation cancelled by user." -ForegroundColor Yellow
exit 0
}
} else {
Write-Host "Quiet mode: Installation proceeding automatically" -ForegroundColor Yellow
}
# If Jdk Path Exists Overwrite
if (Test-Path $JDK_PATH) {
Write-Host "Warning: Target path already exists. Overwriting..." -ForegroundColor Yellow
Remove-Item -Path $JDK_PATH -Recurse -Force
New-Item -Path $JDK_PATH -ItemType Directory -Force | Out-Null
}
# Download and install JDK
$result = Get-PortableJDK -Url $selectedVendor.Url -TargetFolder $JDK_PATH -CachePath $CACHE_PATH
if ($result) {
Write-Host "JDK installation completed successfully!" -ForegroundColor Green
# Create launcher script
$launcherResult = Create-JdkLauncherScript -JdkPath $JDK_PATH -LauncherPath $JDK_SHELL_LAUNCHER_PATH
if ($launcherResult) {
Write-Host "Launcher created successfully. Double-click 'Java Shell.lnk' to start a Java-enabled PowerShell session." -ForegroundColor Green
}
} else {
Write-Host "JDK installation failed." -ForegroundColor Red
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment