When Oracle decided to go with the six-month release cycle for new Java versions, many developers started to work with more than one Java version at a time. It is relatively easy to switch between different versions on a Mac or Linux-based system, thanks to utilities like Jabba and jEnv; But on Windows, this is not as straightforward.
Jabba can install multiple Java versions on a Windows PC machine, but it does not set the corresponding persistent
Path variables for the current user. jEnv, on the other hand, does not work at all on Windows PC machine and can only be used for Mac or Linux based setups.
In the following sections, we will see how we can use Jabba (for installation of various versions) and a custom batch script to switch between these (Jabba installed) versions to solve the issues mentioned earlier.
Installing Jabba is straightforward. All you need to do is run the following command from PowerShell as an administrator.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-Expression ( Invoke-WebRequest https://github.com/shyiko/jabba/raw/master/install.ps1 -UseBasicParsing ).Content
Once Jabba is installed, we can use the same to install different Java versions as per the requirement. You can look into the official documentation for the support. In its simplest version, the following commands will install openjdk15 and adoptOpenJdk8 on the machine:
# fetch and install openjdk versions available in the remote repo jabba ls-remote | grep "openjdk" jabba install email@example.com # fetch and install adoptOpenJdk versions available in the remote repo jabba ls-remote | grep "adopt" jabba install firstname.lastname@example.org
The problem with Jabba is that the
JAVA_HOME variables set via the use command last only the current session. If we need to persist the value of these, we need to manually put these in the environment variables. But when you have more than a few versions installed, manually updating the environment variables to point to the required version quickly becomes a challenge.
I drafted a list of requirements that the script should support. Primarily it should:
- Update the
Pathenvironment variables for the current user.
- It should not update the System environment variables.
- If the
Pathenvironment variable already contains a JDK entry, it should update the same instead of adding a new entry, which might corrupt the setup.
Before we look at the batch-script itself, I want to highlight the following assumptions:
- All the Java versions are setup using Jabba.
- The Java versions are installed on the default location, which is
- The Path variable, if not set based on the JVM_HOME variable (i.e.,
%JAVA_HOME%/bin) and was set manually, will contain the
# a utility script to set java environment variables # as downloaded by jabba (https://github.com/shyiko/jabba) # on a windows10 PC machine # developed by gaurs (https://github.com/gaurs) # updated on: 07-Feb-2021 # posted on jvmaware blog (https://jvmaware.com/blog/multiple-java-versions/) @ECHO OFF SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS SET COUNT=1 SET UPDATED_PATH="" SET CURR_PATH="" IF "%~1"=="ls" (GOTO LS) IF "%~1"=="use" (GOTO USE) ELSE (GOTO NONE) :LS SET FROM=%USERPROFILE%\.jabba\jdk CD %FROM% FOR /F "DELIMS=" %%D in ('DIR /A:D /B') DO ( ECHO %%~D ) EXIT /B 0 :USE SET FROM=%USERPROFILE%\.jabba\jdk CD %FROM% FOR /F "DELIMS=" %%D in ('DIR /A:D /B') DO ( SET name!COUNT!=%%~D SET path!COUNT!=%%~FD SET /a COUNT=!COUNT!+1 ) SET OPTION=%~2 SET NAME=!name%OPTION%! SET LOCATION=!path%OPTION%! ECHO selected option: %NAME% from locaton: %LOCATION% GOTO SETPATHS EXIT /B 0 :SETPATHS ECHO setting the paths for current user only SETX JAVA_HOME %LOCATION% SET Key="HKCU\Environment" FOR /F "USEBACKQ TOKENS=2*" %%A IN (`REG QUERY %Key% /v PATH`) DO SET CURR_PATH=%%B SET List=%CURR_PATH% GOTO :PROCESS_LIST EXIT /B 0 :PROCESS_LIST FOR /F "TOKENS=1* DELIMS=;" %%a IN ("!List!") DO ( IF "%%a" NEQ "" ( ECHO %%a | findstr /C:".jabba\jdk">null SET CODE=%errorlevel% IF "%CODE%"=="1" ( SET UPDATED_PATH=%UPDATED_PATH%;%%JAVA_HOME%%\bin SET CODE=0 )ELSE ( IF "%UPDATED_PATH%"=="""" ( SET UPDATED_PATH=%%a )ELSE ( SET UPDATED_PATH=%UPDATED_PATH%;%%a ) ) ) IF "%%b" NEQ "" ( SET List=%%b GOTO :PROCESS_LIST ) ) GOTO UPDATE_PATH_VALUE EXIT /B 0 :UPDATE_PATH_VALUE ECHO Setting path to: %UPDATED_PATH% SETX PATH "%UPDATED_PATH%" ECHO JAVA_HOME and PATH updated to the selected values for current user EXIT /B 0 :NONE ECHO please enter valid value EXIT /B 0
The script works by listing the currently installed java versions inside the
%USERPROFILE%\.jabba\jdk location, and then the user can select any one of those.
A sample execution of the same looks something like this:
> jdkMan.bat ls email@example.com firstname.lastname@example.org > jdkMan.bat use 1 selected option: email@example.com from locaton: C:\Users\gaurs\.jabba\jdk\firstname.lastname@example.org setting the paths for current user only SUCCESS: Specified value was saved. Setting path to: %USERPROFILE%\AppData\Local\Microsoft\WindowsApps;%JAVA_HOME%\bin;... SUCCESS: Specified value was saved. JAVA_HOME and PATH updated to the selected values for current user
You can check the environment variables for the current user and those should reflect the changes as listed below:
As always, I hope you find this article and the batch script helpful. Please drop me an email if you have any suggestions or queries. I'll try to answer your questions at the earliest.
That's it for now. Keep learning, Keep Coding.
jvm aware newsletter
join the newsletter to receive the latest updates in your inbox.