Running multiple version of JDK in Windows commandLine, the fun? way
zeagur
Posted on September 26, 2022
In this blog I'll walk you through on how to config your various terminal to dynamically switch JDK version in a painless? and a bit cooler way right from your terminal.
Table Of Contents
why not use the wsl?
yes, we can config it easily like we did in any bash in linux, which is cool 😁 and another great thing I found out recently about WSL is that it can execute windows binary file like those exe
directly from wsl terminal.
Don't believe me? here's an example 😜
I'll test on
oc
cli that I'm using to do stuff with my openshift cluster as an example in this case.
- let's start with check where the
oc.exe
is located
- test some command
- now switch to ubuntu wsl terminal and notice the
oc
bin that belong to this ubuntu wsl
- let's test some command, we will noticed the
unauth
response since I didn't share the config between windows/wsl
- now let's
cd
into the windows folder with theexe
file we want to test, in order to access our windows file, the path will have to be pre-fix with/mnt/
and followed by normal drive letter without colon symbol
for example: /mnt/c/windows/system32/
- when call the
oc.exe
file we'll notice the response returned normally instead ofunauth
like the above command, this because we invoked the one that belong in windows env which is the same as we invoked in windowscmd
, amazing isn't it?
ok but that's not the point of this blog, if you're like me who don't like context-switching too much and only use it when neccessery, let's continue see what we can do to run multiple JDK in windows env.
🤖 Prepare JDK and pre-requisites
usually when we installed JDK package through windows installer we'll ended up with something like this
and when we run the java version check it'll run one of these 3 depends on how you installed it, notice that I didn't set the JAVA_HOME
yet
next, you'll need chocolatey package manager for its refreshenv
utility, if you don't want to install chocolatey or other reason, you can get this util directly from chocolatey github then register the bat
in PATH
environment variable
and that's it for preparation part.
💻 Command Prompt
in order to do alias
or other custom command, we'll have to go extra miles(or Km) to config this ol-cmd
terminal(seriously, please replace it with something powerful Microsoft 😗)
- Choose the location to store our new script files, in this case I'll use
cmd_script
in my%userprofile%
to store it
- add it to the
PATH
by going to environment variable settings
- create new folder named
alias
inside the script folder then add it to thePATH
- create new script called
usejdk.cmd
orusejdk.bat
the above process should be the same when you add
refreshEnv.cmd
if you didn't use chocolatey
- add the following script to the
usejdk
bat file
@echo off
set JDK_VERSION=%~1
if "%JDK_VERSION%" == "" (
goto usage
) else if "%JDK_VERSION%" == "8" (
set JAVA_HOME="C:\Program Files\Eclipse Adoptium\jdk-8.0.345.1-hotspot"
)
GOTO :eof
:usage
ECHO Please select your Java Version
ECHO Usage: useJDK [version]
EXIT /B 1
change the JAVA_HOME path to suit your need and add addtional condition if you have more than 2 JDK
- Test the script if it's working correctly
C:\Users\Rujra>usejdk 11
C:\Users\Rujra>echo %JAVA_HOME%
"C:\Program Files\Eclipse Adoptium\jdk-11.0.16.101-hotspot"
C:\Users\Rujra>java -version
openjdk version "1.8.0_345"
OpenJDK Runtime Environment (Temurin)(build 1.8.0_345-b01)
OpenJDK 64-Bit Server VM (Temurin)(build 25.345-b01, mixed mode)
C:\Users\Rujra>
noticed that even though we set the
JAVA_HOME
the java runtime didn't changed, that's because it's registered inPATH
env, hardcoded.
- this can be solve in 2 ways
- remove the jdk/bin path from our
PATH
env then add a new one with%JAVA_HOME%\bin
- leave it be but move those down to the bottom of
PATH
env then add the java home from1.
and move it up to the top- this method can be useful if you want to run something like
where java
which will list all knows java binary inPATH
- this method can be useful if you want to run something like
- remove the jdk/bin path from our
- let's try again ```shell
C:\Users\Rujra>usejdk 11
C:\Users\Rujra>echo %JAVA_HOME%
"C:\Program Files\Eclipse Adoptium\jdk-11.0.16.101-hotspot"
C:\Users\Rujra>java -version
openjdk version "1.8.0_345"
OpenJDK Runtime Environment (Temurin)(build 1.8.0_345-b01)
OpenJDK 64-Bit Server VM (Temurin)(build 25.345-b01, mixed mode)
> still not working 😾
- now let's check the `PATH`
```shell
C:\Users\Rujra>PATH
PATH=C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.14.2282.0_x64__8wekyb3d8bbwe;%JAVA_HOME%\bin;[other path env blah blah blah];
noticed the %JAVA_HOME% in PATH? that's where our
refreshenv
will come into play next
- modify the
usejdk
script with our long-awaitedrefreshenv
util ```shell
...
) else if "%JDK_VERSION%" == "8" (
set JAVA_HOME="C:\Program Files\Eclipse Adoptium\jdk-8.0.345.1-hotspot"
refreshenv
)
...
- third?? time's a charm, I hope 😗.
```shell
C:\Users\Rujra>usejdk 11
Refreshing environment variables from registry for cmd.exe. Please wait...Finished..
C:\Users\Rujra>PATH
PATH="C:\Program Files\Eclipse Adoptium\jdk-11.0.16.101-hotspot"\bin;[other path env blah blah blah];
C:\Users\Rujra>java -version
openjdk version "11.0.16.1" 2022-08-12
OpenJDK Runtime Environment Temurin-11.0.16.1+1 (build 11.0.16.1+1)
OpenJDK 64-Bit Server VM Temurin-11.0.16.1+1 (build 11.0.16.1+1, mixed mode)
now it's working, WOW, so easy! 🤯 I almost had a migraine tbh🤷♂️.
💠 Powershell 5 & 7
In powershell, it's a bit easier to manipulate the env var/alias since everything is stored inside "special" env:
and alias:
PSdrive
why is it matters? because we will use these to help us switch between multiple JDK in a moment
! important: before we proceed please make sure you have set the
PATH
variable with%JAVA_HOME%\bin
at the top like we did inCMD
steps
Environment Variable
to display the current env we can do the following
PS C:\Users\Rujra> dir env:
Name Value
---- -----
ALLUSERSPROFILE C:\ProgramData
ChocolateyInstall C:\ProgramData\chocolatey
to query specific key, just add the key to path
dir env:\some_thing
to query value only, add$
to env$env:some_thing
Alias
to display Alias is the same as Env var
PS C:\Users\Rujra> dir alias:
CommandType Name Version Source
----------- ---- ------- ------
Alias % -> ForEach-Object
Alias ? -> Where-Object
Alias CFS -> ConvertFrom-String 3.1.0.0 Microsoft.PowerShell.Utility
to query specific key, just add the key to path
dir alias:\some_thing
to query value only, add$
to env$alias:some_thing
Steps
- in order to persist configuration across terminal session we'll have to create a profile for powershell by do the following command
new-item -path $profile -itemtype file -force
- now open the profile in your favourite ide and add the following script
function java8 {
$Env:JAVA_HOME = "[your JDK ROOT PATH]"
refreshenv
}
function java11 {
$Env:JAVA_HOME = "[your JDK ROOT PATH]"
refreshenv
}
...
- re-open your powershell and see if the function getting load normally, however on the first time you might ran into this problem
. : File ...\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 cannot be loaded because
running scripts is disabled on this system. For more information, see about_Execution_Policies at
https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:3
+ . '...\WindowsPowerShell\Microsoft.Powe ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
this stackoverflow answer give a great explanation on how to solve this issue without compromise much of your machine security
- after powershell started successfully, now it's the time to test our little script
PS C:\Users\Rujra> java8
Refreshing environment variables from registry for cmd.exe. Please wait...Finished..
PS C:\Users\Rujra> $env:PATH
%JAVA_HOME%\bin;[other PATH env blah blah blah]
PS C:\Users\Rujra> $env:JAVA_HOME
C:\Program Files\Eclipse Adoptium\jdk-8.0.345.1-hotspot
PS C:\Users\Rujra> java -version
openjdk version "17.0.4.1" 2022-08-12
OpenJDK Runtime Environment Temurin-17.0.4.1+1 (build 17.0.4.1+1)
OpenJDK 64-Bit Server VM Temurin-17.0.4.1+1 (build 17.0.4.1+1, mixed mode, sharing)
noticed that even with
refreshenv
it didn't worked, this is because it refreshcmd.exe
and notpowershell.exe
we'll have to come up with another solution
- from previous test, we'll see that it didn't worked as we expected, so, let's try another method by modify our script as below
function java8 {
$Env:JAVA_HOME = "[your JDK ROOT PATH]"
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine")
}
function java11 {
$Env:JAVA_HOME = "[your JDK ROOT PATH]"
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine")
}
...
this will replace
refreshenv
with manually load new env var from the machine env var to currentpowershell
session
- now let's close and re-open
powershell
and see if this time it working correctly.
PS C:\Users\Rujra> $env:PATH
%JAVA_HOME%\bin;[other PATH env blah blah blah]
PS C:\Users\Rujra> java -version
openjdk version "17.0.4.1" 2022-08-12
OpenJDK Runtime Environment Temurin-17.0.4.1+1 (build 17.0.4.1+1)
OpenJDK 64-Bit Server VM Temurin-17.0.4.1+1 (build 17.0.4.1+1, mixed mode, sharing)
PS C:\Users\Rujra> $env:JAVA_HOME
PS C:\Users\Rujra> java11
PS C:\Users\Rujra> $env:PATH
C:\Program Files\Eclipse Adoptium\jdk-11.0.16.101-hotspot\bin;[other PATH env blah blah blah]
PS C:\Users\Rujra> $env:JAVA_HOME
C:\Program Files\Eclipse Adoptium\jdk-11.0.16.101-hotspot
PS C:\Users\Rujra> java -version
openjdk version "11.0.16.1" 2022-08-12
OpenJDK Runtime Environment Temurin-11.0.16.1+1 (build 11.0.16.1+1)
OpenJDK 64-Bit Server VM Temurin-11.0.16.1+1 (build 11.0.16.1+1, mixed mode)
now it's working, a bit easier to config than
CMD
for sure, cheers 🥂
🖲️ Cmder
Now we've come to the last terminal I'll config for this blog, The powerful Cmder
Cmder itself has many features off-the-shelf including linux commands that you can use alongside your normal windows commands whether it's ls -lha
dir
etc, but now I'll add a bit more power to it by adding ability to dynamically switch JDK version with alias.
! important: before we proceed please make sure you have set the
PATH
variable with%JAVA_HOME%\bin
at the top like we did inCMD
orPowershell
steps
- first, after you've downloaded and extracted cmder to your machine, you'll have something like this below
D:\Programs\Cmder
λ ls -lha
total 169K
drwxr-xr-x 1 Rujra 197609 0 Feb 3 2022 ./
drwxr-xr-x 1 Rujra 197609 0 Sep 4 13:47 ../
drwxr-xr-x 1 Rujra 197609 0 Jan 26 2020 bin/
-rwxr-xr-x 1 Rujra 197609 139K Jan 17 2022 Cmder.exe*
-rw-r--r-- 1 Rujra 197609 33 Mar 9 2020 cmder_shell.bat
drwxr-xr-x 1 Rujra 197609 0 Sep 27 18:56 config/
drwxr-xr-x 1 Rujra 197609 0 Jan 26 2020 icons/
-rw-r--r-- 1 Rujra 197609 1.1K Jan 17 2022 LICENSE
drwxr-xr-x 1 Rujra 197609 0 Oct 31 2021 opt/
drwxr-xr-x 1 Rujra 197609 0 Feb 3 2022 vendor/
-rw-r--r-- 1 Rujra 197609 0 Jan 17 2022 'Version 1.3.19.1181'
- inside
config
folder there will be some config files, but we will be focus on 2 configs only- user_aliases.cmd
- user_profile.cmd
D:\Programs\Cmder\config
λ ls -lha
total 508K
drwxr-xr-x 1 Rujra 197609 0 Sep 27 18:58 ./
drwxr-xr-x 1 Rujra 197609 0 Feb 3 2022 ../
-rw-r--r-- 1 Rujra 197609 4.2K Sep 27 18:58 clink.log
-rw-r--r-- 1 Rujra 197609 377K Sep 27 18:56 clink_history
-rw-r--r-- 1 Rujra 197609 121 Sep 27 18:58 clink_history_23924
-rw-r--r-- 1 Rujra 197609 97 Sep 27 18:56 clink_history_23924.removals
-rw-r--r-- 1 Rujra 197609 0 Sep 27 18:56 clink_history_23924~
-rw-r--r-- 1 Rujra 197609 507 Oct 31 2021 clink_settings
-rw-r--r-- 1 Rujra 197609 2.0K Mar 16 2022 cmder_prompt_config.lua
-rw-r--r-- 1 Rujra 197609 29K May 11 2021 mini_dump.dmp
drwxr-xr-x 1 Rujra 197609 0 Feb 3 2022 profile.d/
-rw-r--r-- 1 Rujra 197609 887 Jan 17 2022 Readme.md
-rw-r--r-- 1 Rujra 197609 672 Sep 26 19:29 user_aliases.cmd
-rw-r--r-- 1 Rujra 197609 967 Sep 26 18:42 user_profile.cmd
-rw-r--r-- 1 Rujra 197609 408 Dec 23 2018 user_profile.ps1
-rw-r--r-- 1 Rujra 197609 54K Jun 23 16:18 user-ConEmu.xml
- inside
user_profile.cmd
add the following config ```bat
...
:: JAVA config
set JAVA_8_HOME="[your JDK ROOT PATH]"
set JAVA_11_HOME="[your JDK ROOT PATH]"
:: Other jdk you're using
...
- now after we set env on the profile, we'll set alias in `user_aliases.cmd` to switch the java version whenever we needed.
```bat
;= JAVA_HOME
java8=set JAVA_HOME=%JAVA_8_HOME%&refreshenv
java11=set JAVA_HOME=%JAVA_11_HOME%&refreshenv
- saves and open up
Cmder
and let's try the new alias
C:\Users\Rujra
λ echo %PATH%
%JAVA_HOME%\bin;[other PATH env blah blah blah];
C:\Users\Rujra
λ echo %JAVA_HOME%
%JAVA_HOME%
C:\Users\Rujra
λ java -version
openjdk version "17.0.4.1" 2022-08-12
OpenJDK Runtime Environment Temurin-17.0.4.1+1 (build 17.0.4.1+1)
OpenJDK 64-Bit Server VM Temurin-17.0.4.1+1 (build 17.0.4.1+1, mixed mode, sharing)
C:\Users\Rujra
λ java11
Refreshing environment variables from registry for cmd.exe. Please wait...Finished..
C:\Users\Rujra
λ echo %PATH%
"C:\Program Files\Eclipse Adoptium\jdk-11.0.16.101-hotspot"\bin;[other PATH env blah blah blah];
C:\Users\Rujra
λ echo %JAVA_HOME%
"C:\Program Files\Eclipse Adoptium\jdk-11.0.16.101-hotspot"
C:\Users\Rujra
λ java -version
openjdk version "11.0.16.1" 2022-08-12
OpenJDK Runtime Environment Temurin-11.0.16.1+1 (build 11.0.16.1+1)
OpenJDK 64-Bit Server VM Temurin-11.0.16.1+1 (build 11.0.16.1+1, mixed mode)
work like a charm 😁👾
and that's it, thank you for reading, this is my first (finished)blog, any feedbacks & suggestions are gladly welcome! 🙌
Posted on September 26, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.