繁体   English   中英

在 Windows 中切换不同的 JDK 版本

[英]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选项用于设置变量系统范围(而不仅仅是当前用户)。 终端必须以管理员身份运行才能使用此选项。

该变量将在所有新终端窗口中可用,但在当前窗口中不可用。 如果您还想在同一窗口中使用路径,则需要同时使用setsetx

如果您只将%JAVA_HOME%放在那里,而不是完整的 JDK 路径,则可以避免操作PATH变量。 如果您更改JAVA_HOMEPATH也将被更新。


还有一些环境变量编辑器可以替代繁琐的 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 8SJV它将切换到 Java 8。

我希望这对想要经常更改它的人有所帮助。

  1. 打开Environment Variables编辑器(文件资源管理器>右键单击此电脑>属性>高级系统设置>环境变量...)
  2. 系统变量列表中找到Path变量 > 按编辑 > 放入%JAVA_HOME%bin; 在第一位置。 这是必需的,因为 Java 安装程序将C:\Program Files (x86)\Common Files\Oracle\Java\javapath到引用最新安装的 Java 版本的PATH中。 在此处输入图像描述
  3. 现在您可以使用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 版本。

优点:

  1. 它不会修改 PATH 系统环境变量。
  2. 唯一需要维护的是关系数组(可以方便地构造为稀疏数组),其中包含版本号和脚本开头的路径。

前提:

以下条目%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 版本设置为单独的变量。

  1. Java_8_home-> 指向本地的 Java 8 位置
  2. Java_11_home -> 指向本地的 Java 11 位置
  3. Java_17_home -> 指向本地的 Java 17 位置
  4. Java_Home->这里指向你要使用的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 为Java11Java17Java8手动创建了环境变量。 要跨 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM