DEV Community

zeagur
zeagur

Posted on

Running multiple version of JDK in Windows commandLine, the fun? way

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

Image description

  • test some command

Image description

  • now switch to ubuntu wsl terminal and notice the oc bin that belong to this ubuntu wsl

Image description

  • let's test some command, we will noticed the unauth response since I didn't share the config between windows/wsl

Image description

  • now let's cd into the windows folder with the exe 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/

Image description

  • when call the oc.exe file we'll notice the response returned normally instead of unauth like the above command, this because we invoked the one that belong in windows env which is the same as we invoked in windows cmd, amazing isn't it?

Image description


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

Image description

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

Image description

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


create new folder to use as script location


  • add it to the PATH by going to environment variable settings


type env in search bar



click on Environment Variable



look for PATH then edit it to add our script location we created earlier


  • create new folder named alias inside the script folder then add it to the PATH


alias folder will serve as our alias


  • create new script called usejdk.cmd or usejdk.bat


create new script in the script folder

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

noticed that even though we set the JAVA_HOME the java runtime didn't changed, that's because it's registered in PATH env, hardcoded.


the hard-coded path env that we didn't touch earlier


  • this can be solve in 2 ways
    1. remove the jdk/bin path from our PATH env then add a new one with %JAVA_HOME%\bin
    2. leave it be but move those down to the bottom of PATH env then add the java home from 1. 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 in PATH


the PATH env after some changes


  • let's try again
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)
Enter fullscreen mode Exit fullscreen mode

still not working 😾

  • now let's check the PATH
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];
Enter fullscreen mode Exit fullscreen mode

noticed the %JAVA_HOME% in PATH? that's where our refreshenv will come into play next

  • modify the usejdk script with our long-awaited refreshenv util
...
) else if "%JDK_VERSION%" == "8" (
    set JAVA_HOME="C:\Program Files\Eclipse Adoptium\jdk-8.0.345.1-hotspot"
    refreshenv
)
...
Enter fullscreen mode Exit fullscreen mode
  • third?? time's a charm, I hope 😗.
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)
Enter fullscreen mode Exit fullscreen 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 in CMD 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  • 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
}
...
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

noticed that even with refreshenv it didn't worked, this is because it refresh cmd.exe and not powershell.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")
}
...
Enter fullscreen mode Exit fullscreen mode

this will replace refreshenv with manually load new env var from the machine env var to current powershell 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)
Enter fullscreen mode Exit fullscreen 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 in CMD or Powershell 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'
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode
  • inside user_profile.cmd add the following config
...
:: JAVA config
set JAVA_8_HOME="[your JDK ROOT PATH]"
set JAVA_11_HOME="[your JDK ROOT PATH]"
:: Other jdk you're using
...
Enter fullscreen mode Exit fullscreen mode
  • now after we set env on the profile, we'll set alias in user_aliases.cmd to switch the java version whenever we needed.
;= JAVA_HOME

java8=set JAVA_HOME=%JAVA_8_HOME%&refreshenv
java11=set JAVA_HOME=%JAVA_11_HOME%&refreshenv
Enter fullscreen mode Exit fullscreen mode
  • 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)
Enter fullscreen mode Exit fullscreen 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! 🙌


Top comments (0)