[英]Switching between different JDK versions in Windows
我正在處理幾個項目,其中一些項目使用不同的 JDK。 在 JDK 版本之間切換並不方便。 所以我想知道是否有任何簡單的方法可以改變它?
我找到了兩種方法,應該可以解決這個問題,但它不起作用。
第一個解決方案是創建一個像這樣的 bat 文件:
@echo off
echo Setting JAVA_HOME
set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_72
echo setting PATH
set PATH=C:\Program Files\Java\jdk1.7.0_72\bin;%PATH%
echo Display java version
java -version
pause
在運行這個 bat 之后,我看到了正確的 Java 版本。 但是當我關閉這個 CMD 並打開一個新的並輸入“java -version”時,它說我還有 1.8.0_25。 所以它不起作用。
我發現的第二個解決方案是這個站點的一個應用程序。 而且它也不起作用。 與第一個解決方案中的效果相同。
有任何想法嗎? 因為通過以下方式更改 JAVA_HOME 和 PAHT:Win + Pause -> Advanced System Settings -> Environment Variables -> 並編輯這些變量,是一種糟糕的方式......
set
命令僅適用於當前終端。 要永久設置系統或用戶環境變量,您可以使用setx
。
setx JAVA_HOME "C:\Program Files\Java\jdk1.7.0_72" /m
/m
選項用於設置變量系統范圍(而不僅僅是當前用戶)。 終端必須以管理員身份運行才能使用此選項。
該變量將在所有新終端窗口中可用,但在當前窗口中不可用。 如果您還想在同一窗口中使用路徑,則需要同時使用set
和setx
。
如果您只將%JAVA_HOME%
放在那里,而不是完整的 JDK 路徑,則可以避免操作PATH
變量。 如果您更改JAVA_HOME
, PATH
也將被更新。
還有一些環境變量編輯器可以替代繁瑣的 Windows 環境變量設置。 請參閱超級用戶上的“ 在 Windows 7 中是否有一種方便的方式來編輯 PATH? ”。
如果有人想在每個新的命令窗口中頻繁切換,那么我將使用以下方法。
命令提示符版本:
使用以下代碼創建批處理文件。 您可以使用 if 和 else 塊添加 n 個版本。
@echo off
if "%~1" == "11" (
set "JAVA_HOME=C:\Software\openjdk-11+28_windows-x64_bin\jdk-11"
) else (
set "JAVA_HOME=C:\Program Files\Java\jdk1.8.0_151"
)
set "Path=%JAVA_HOME%\bin;%Path%"
java -version
將此批處理文件另存為 SJV.bat 並將此文件位置添加到計算機的 Path 環境變量中。 所以現在 SJV 將充當“切換 Java 版本”的命令。
現在打開新的命令窗口,只需鍵入SJV 11
它將切換到 Java 11。鍵入SJV 8
它將切換到 Java 8。
PowerShell 版本
使用以下代碼創建 powershell(ps1) 文件。 您可以使用 if 和 else 塊添加 n 個版本。
If($args[0] -eq "11")
{
$env:JAVA_HOME = 'C:\Software\openjdk-11+28_windows-x64_bin\jdk-11'
}else{
$env:JAVA_HOME = 'C:\Program Files\Java\jdk1.8.0_151'
}
$env:Path = $env:JAVA_HOME+'\bin;'+$env:Path
java -version
將此腳本文件另存為 SJV.ps1 並將此文件位置添加到計算機的 Path 環境變量中。 所以現在 SJV 將充當“切換 Java 版本”的命令。
現在打開新的 powershell 窗口,只需鍵入SJV 11
它將切換到 Java 11。鍵入SJV 8
或SJV
它將切換到 Java 8。
我希望這對想要經常更改它的人有所幫助。
Environment Variables
編輯器(文件資源管理器>右鍵單擊此電腦>屬性>高級系統設置>環境變量...)Path
變量 > 按編輯 > 放入%JAVA_HOME%bin;
在第一位置。 這是必需的,因為 Java 安裝程序將C:\Program Files (x86)\Common Files\Oracle\Java\javapath
到引用最新安裝的 Java 版本的PATH
中。 現在您可以使用setx
命令在 Java 版本之間切換(應在管理權限下運行):
setx /m JAVA_HOME "c:\Program Files\Java\jdk-10.0.1\
(注意:行尾沒有雙引號,不應該是雙引號,否則你會在你的JAVA_HOME
變量中得到c:\Program Files\Java\jdk-10.0.1\"
並且它會破壞你的PATH
變量)
具有系統變量(和管理權限)的解決方案更加健壯,因為它將所需的 Java 路徑放在生成的PATH
變量的開頭。
如果您的路徑少於 1024 個字符,則可以執行(以管理員身份運行)此腳本:
@echo off
set "JAVA5_FOLDER=C:\Java\jdk1.5.0_22"
set "JAVA6_FOLDER=C:\Java\jdk1.6.0_45"
set "JAVA7_FOLDER=C:\Java\jdk1.7.0_80"
set "JAVA8_FOLDER=C:\Java\jdk1.8.0_121"
set "JAVA9_FOLDER=C:\Java\jdk-10.0.1"
set "CLEAR_FOLDER=C:\xxxxxx"
(echo "%PATH%" & echo.) | findstr /O . | more +1 | (set /P RESULT= & call exit /B %%RESULT%%)
set /A STRLENGTH=%ERRORLEVEL%
echo path length = %STRLENGTH%
if %STRLENGTH% GTR 1024 goto byebye
echo Old Path: %PATH%
echo ===================
echo Choose new Java Version:
echo [5] JDK5
echo [6] JDK6
echo [7] JDK7
echo [8] JDK8
echo [9] JDK10
echo [x] Exit
:choice
SET /P C=[5,6,7,8,9,x]?
for %%? in (5) do if /I "%C%"=="%%?" goto JDK_L5
for %%? in (6) do if /I "%C%"=="%%?" goto JDK_L6
for %%? in (7) do if /I "%C%"=="%%?" goto JDK_L7
for %%? in (8) do if /I "%C%"=="%%?" goto JDK_L8
for %%? in (9) do if /I "%C%"=="%%?" goto JDK_L9
for %%? in (x) do if /I "%C%"=="%%?" goto byebye
goto choice
@echo on
:JDK_L5
set "NEW_PATH=%JAVA5_FOLDER%"
goto setPath
:JDK_L6
@echo off
set "NEW_PATH=%JAVA6_FOLDER%"
goto setPath
:JDK_L7
@echo off
set "NEW_PATH=%JAVA7_FOLDER%"
goto setPath
:JDK_L8
@echo off
set "NEW_PATH=%JAVA8_FOLDER%"
goto setPath
:JDK_L9
@echo off
set NEW_PATH = %JAVA9_FOLDER%
:setPath
Call Set "PATH=%%PATH:%JAVA5_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA6_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA7_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA8_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA9_FOLDER%=%CLEAR_FOLDER%%%"
rem echo Interim Path: %PATH%
Call Set "PATH=%%PATH:%CLEAR_FOLDER%=%NEW_PATH%%%"
setx PATH "%PATH%" /M
call set "JAVA_HOME=%NEW_PATH%"
setx JAVA_HOME %JAVA_HOME%
echo New Path: %PATH%
:byebye
echo
java -version
pause
如果超過 1024,請嘗試刪除一些不必要的路徑,或者可以使用來自https://superuser.com/questions/387619/overcoming-the-1024-character-limit-with-setx的一些輸入來修改此腳本
運行此 BAT 文件可以方便地更改 java 版本。
以下條目%JAVA_HOME%\bin
必須附加到PATH
環境變量中。
@echo off
@cls
@title Switch Java Version
setlocal EnableExtensions DisableDelayedExpansion
:: This bat file Switches the Java Version using the JAVA_HOME variable.
:: This script does NOT modify the PATH system environment variable.
:: Precondition: The following entry "%JAVA_HOME%\bin" has to be appended to the PATH environment variable.
:: Script Name: SwitchJavaVersion | Version 1 | 2021/11/04
rem Add items to vector as follows:
rem AvailableVersions["Java Major Version Number"]="Java Absolute Path"
set AvailableVersions[8]="D:\Program Files\Java\jdk8u252-b09"
set AvailableVersions[17]="D:\Program Files\Java\jdk-17.0.1"
call :PrintJavaVersion
call :PrintAvailableVersions
call :GetJavaVersion
call :SetJavaVersion
call :ResetLocalPath
if %errorlevel% neq 0 exit /b %errorlevel%
call :PrintJavaVersion
pause
endlocal
exit /b
rem Print available versions.
:PrintAvailableVersions
echo Available Java Versions:
for /f "tokens=2 delims=[]" %%I in ('set AvailableVersions[') do echo ^> %%I
exit /b
rem Get version from user input or command-line arguments.
:GetJavaVersion
set "JavaVersion="
if "%~1"=="" (
set /p JavaVersion="Type the major java version number you want to switch to: "
) else (
set /a JavaVersion="%~1"
)
exit /b
rem Update JAVA_HOME user variable with hardcoded paths.
:SetJavaVersion
set JavaPath=
for /f "tokens=2 delims=[]" %%I in ('set AvailableVersions[') do (
if "%%I" == "%JavaVersion%" (
setlocal EnableDelayedExpansion
set JavaPath=!AvailableVersions[%%I]!
setlocal EnableExtensions DisableDelayedExpansion
)
)
if not defined JavaPath (
echo "Specified version NOT found: Default settings applied."
for /f "tokens=2 delims==" %%I in ('set AvailableVersions[') do (
set JavaPath=%%I
goto exitForJavaPath
)
)
:exitForJavaPath
rem remove quotes from path
set JavaPath=%JavaPath:"=%
set "JAVA_HOME=%JavaPath%"
setx JAVA_HOME "%JAVA_HOME%"
rem setlocal statement was run 2 times previously inside the for loop; therefore, the endlocal statement must be executed 2 times to close those nested local scopes.
rem below endlocal statement will close local scope set by previous "setlocal EnableExtensions DisableDelayedExpansion" statement
endlocal & set "JavaPath=%JavaPath%"
rem JAVA_HOME's value rolls back due to endlocal statement so the appropriate value has to be reassigned
set "JAVA_HOME=%JavaPath%"
rem below endlocal statement will close local scope set by previous "setlocal EnableDelayedExpansion" statement
endlocal & set "JavaPath=%JavaPath%"
rem JAVA_HOME's value rolls back due to endlocal statement so the appropriate value has to be reassigned
set "JAVA_HOME=%JavaPath%"
exit /b
rem Get User and System Path variable's definition from Registry,
rem evaluate the definitions with the new values and reset
rem the local path variable so newly set java version
rem is properly displayed.
:ResetLocalPath
set "PathValue="
for /F "skip=2 tokens=1,2,*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V Path') do if /I "%%I" == "Path" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "PathValue=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "PathValue=%%~K"
if not defined PathValue goto pathError
set "UserPathValue="
for /F "skip=2 tokens=1,2,*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKCU\Environment" /V Path') do if /I "%%I" == "Path" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "UserPathValue=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "UserPathValue=%%~K"
if not defined UserPathValue goto pathError
call set "Path=%PathValue%;%UserPathValue%"
echo Path variable reset:
echo PATH=%Path%
echo.
exit /b
rem Display the Java version.
:PrintJavaVersion
echo Current Java Version:
java -version
echo.
exit /b
rem Error handling subroutine.
:pathError
echo.
echo Error while refreshing the PATH variable:
echo PathValue=%PathValue%
echo UserPathValue=%UserPathValue%
pause
exit /b 2
endlocal
exit
在 PowerShell 開始時加載下面提到的 PowerShell 腳本。 或使用New-Item $profile -Type File -Force
生成文件,這將在此處創建一個文件C:\Users\{user_name}\Documents\WindowsPowerShell\Microsoft.PowerShell_profile
現在復制粘貼下面給出的內容在每次啟動 PowerShell 時加載的文件中
將您需要的所有 java 版本設置為單獨的變量。
在 power shell 中運行以將版本更新為 8 update_java_version 8 $True
要更新執行策略以允許在 PowerShell 啟動時加載腳本,請使用以下命令Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
`
function update_java_version($version, [bool] $everywhere)
{
switch ($version)
{
8 {
$java_value = (Get-Item Env:Java_8_home).value
$Env:Java_Home = $java_value
refresh-path
break
}
11 {
$java_value = (Get-Item Env:Java_11_home).value
$Env:Java_Home = $java_value
refresh-path
break
}
17 {
$java_value = (Get-Item Env:Java_17_home).value
$Env:Java_Home = $java_value
refresh-path
break
}
default {
throw "No matching java version found for `$version`: $version"
}
}
if ($everywhere)
{
[System.Environment]::SetEnvironmentVariable("Java_Home", $java_value, "User")
}
}
function refresh-path
{
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") +
";" +
[System.Environment]::GetEnvironmentVariable("Path", "User")
}
添加到此處提供的答案( https://stackoverflow.com/a/64459399/894565 )。
我通過 UI 為Java11
、 Java17
和Java8
手動創建了環境變量。 要跨 Java 版本進行更改:
從 powershell ( PJV.ps1
):
if($args[0] -eq "11") {
$Env:JAVA_HOME="$ENV:JAVA11"
$Env:Path="$Env:JAVA_HOME\bin;$Env:Path"
} elseif($args[0] -eq "17") {
$Env:JAVA_HOME="$ENV:JAVA17"
$Env:Path="$Env:JAVA_HOME\bin;$Env:Path"
} elseif($args[0] -eq "8") {
$Env:JAVA_HOME="$ENV:JAVA8"
$Env:Path="$Env:JAVA_HOME\bin;$Env:Path"
}
set "Path=%JAVA_HOME%\bin;%Path%"
java -version
從命令行( JV.bat
):
@echo off
if "%~1" == "11" (
set "JAVA_HOME=%JAVA11%"
setx JAVA_HOME "%JAVA11%"
) else if "%~1" == "17" (
set "JAVA_HOME=%JAVA17%"
setx JAVA_HOME "%JAVA17%"
) else (
set "JAVA_HOME=%JAVA8%"
setx JAVA_HOME "%JAVA8%"
)
set "Path=%JAVA_HOME%\bin;%Path%"
java -version
最后,這兩個文件都在同一個文件夾中。 並且此文件夾路徑已添加到我的系統PATH
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.