You have most probably faced the following situation: You download Java (In this case, the Java Development Kit) from the Oracle website, install it on your system but then pull a project from Github that has a different version, most probably a more recent version. Then you need to go online and look for a newer Java version somewhere. Or even worse, you have Java 11 installed, but you are currently working on a project that only works on Java 8. This is quite a common situation to come across for people who work on different projects. That’s why in this post I will share with you a few ways of overcoming those problems.
We need a way to easily switch between different Java versions, either permanently or for the current session. Some IDEs can easily do the trick, but I like to have an IDE-agnostic way of doing it.
SDKMAN! is an awesome tool that helps you manage not only JDK versions and updates but also Maven, Gradle and many other tools. SDKMAN! is a command-line tool, which facilitates any automation you might want to do.
If you are in a UNIX-like system, the installation is easy as cake. If you’re on Windows, things get a bit more complicated, but it’s still possible.
For UNIX-like systems, you only need two commands to install SDKMAN!
First, you download and install it with one command:
$ curl -s "https://get.sdkman.io" | bash
Then you can either close the current terminal and open a new one or just execute the following command:
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
This will make SDKMAN! available on your terminal.
If everything worked just fine, you should be able to retrieve the SDKMAN! version with the following command:
$ sdk version
Now, let’s learn how to list and how to install java versions.
In order to list the Java versions available, you can run the following command:
$ sdk list java
This command will return a list of Vendors as well as their versions available to install:
================================================================================
Available Java Versions
================================================================================
Vendor | Use | Version | Dist | Status | Identifier
--------------------------------------------------------------------------------
AdoptOpenJDK | | 14.0.1.j9 | adpt | | 14.0.1.j9-adpt
| >>> | 14.0.1.hs | adpt | installed | 14.0.1.hs-adpt
| | 13.0.2.j9 | adpt | | 13.0.2.j9-adpt
| | 13.0.2.hs | adpt | | 13.0.2.hs-adpt
| | 12.0.2.j9 | adpt | | 12.0.2.j9-adpt
| | 12.0.2.hs | adpt | | 12.0.2.hs-adpt
| | 11.0.7.j9 | adpt | | 11.0.7.j9-adpt
| | 11.0.7.hs | adpt | installed | 11.0.7.hs-adpt
| | 8.0.252.j9 | adpt | | 8.0.252.j9-adpt
| | 8.0.252.hs | adpt | installed | 8.0.252.hs-adpt
Amazon | | 11.0.7 | amzn | | 11.0.7-amzn
| | 8.0.252 | amzn | | 8.0.252-amzn
Azul Zulu | | 14.0.1 | zulu | | 14.0.1-zulu
| | 13.0.3 | zulu | | 13.0.3-zulu
| | 13.0.3.fx | zulu | | 13.0.3.fx-zulu
| | 12.0.2 | zulu | | 12.0.2-zulu
| | 11.0.7 | zulu | | 11.0.7-zulu
| | 11.0.7.fx | zulu | | 11.0.7.fx-zulu
| | 10.0.2 | zulu | | 10.0.2-zulu
| | 9.0.7 | zulu | | 9.0.7-zulu
| | 8.0.252 | zulu | | 8.0.252-zulu
| | 8.0.252.fx | zulu | | 8.0.252.fx-zulu
| | 8.0.232.fx | zulu | | 8.0.232.fx-zulu
| | 7.0.262 | zulu | | 7.0.262-zulu
| | 6.0.119 | zulu | | 6.0.119-zulu
BellSoft | | 14.0.1.fx | librca | | 14.0.1.fx-librca
| | 14.0.1 | librca | | 14.0.1-librca
| | 13.0.2.fx | librca | | 13.0.2.fx-librca
| | 13.0.2 | librca | | 13.0.2-librca
| | 12.0.2 | librca | | 12.0.2-librca
| | 11.0.7.fx | librca | | 11.0.7.fx-librca
| | 11.0.7 | librca | | 11.0.7-librca
| | 8.0.252.fx | librca | | 8.0.252.fx-librca
| | 8.0.252 | librca | | 8.0.252-librca
GraalVM | | 20.1.0.r11 | grl | | 20.1.0.r11-grl
| | 20.1.0.r8 | grl | | 20.1.0.r8-grl
| | 20.0.0.r11 | grl | | 20.0.0.r11-grl
| | 20.0.0.r8 | grl | | 20.0.0.r8-grl
| | 19.3.1.r11 | grl | | 19.3.1.r11-grl
| | 19.3.1.r8 | grl | | 19.3.1.r8-grl
Java.net | | 16.ea.4 | open | | 16.ea.4-open
| | 15.ea.30 | open | | 15.ea.30-open
| | 14.0.1 | open | | 14.0.1-open
| | 13.0.2 | open | | 13.0.2-open
| | 12.0.2 | open | | 12.0.2-open
| | 11.0.7 | open | | 11.0.7-open
| | 10.0.2 | open | | 10.0.2-open
| | 9.0.4 | open | | 9.0.4-open
| | 8.0.252 | open | | 8.0.252-open
SAP | | 14.0.1 | sapmchn | | 14.0.1-sapmchn
| | 13.0.2 | sapmchn | | 13.0.2-sapmchn
| | 12.0.2 | sapmchn | | 12.0.2-sapmchn
| | 11.0.7 | sapmchn | | 11.0.7-sapmchn
================================================================================
Use the Identifier for installation:
$ sdk install java 11.0.3.hs-adpt
================================================================================
As you can see, I already have a couple of versions installed. I like to use AdoptOpenJDK but you can use any Vendor you prefer. You may check the vendors and versions on the SDKMAN! official website as well.
The list above already gives you a hint on how to install specific versions of Java. Let’s suppose I’d like to install JDK 8 from Amazon. To do so, I’d run the following command:
$ sdk install java 8.0.252-amzn
Just remember that every version has a specific Identifier and you need to pass that Identifier as an argument to the command. There’s a specific column with the Identifier when you list the versions, you can check in the list of versions above.
If it’s the first time you are installing a version of Java, SDKMAN! will automatically set this version as your default, globally. This means that your JAVA_HOME variable will point to this version you just installed. SDKMAN! does that automatically for you. When you install a new version, SDKMAN! will ask you if you’d like to have this new version as the default (set in your JAVA_HOME) or you’d rather keep the current version.
For example, I’m able to find out my current version (where my JAVA_HOME environment variable is pointing at) running the following command:
$ sdk current java
Which returns the following:
Using java version 14.0.1.hs-adpt
In the example below, I’m installing Java 13 bundled with Java FX from Azul Zulu.
Installing: java 13.0.3.fx-zulu
renamed '/home/derik/.sdkman/tmp/out/zulu13.31.11-ca-fx-jdk13.0.3-linux_x64' -> '/home/derik/.sdkman/candidates/java/13.0.3.fx-zulu'
Done installing!
Do you want java 13.0.3.fx-zulu to be set as default? (Y/n):
As you can see above, after installing it, I’m asked if I want to replace my current default version with Java 13 instead.
Likewise, if you wish to remove a specific version, you can run the following command:
$ sdk uninstall java 13.0.3.fx-zulu
“Ok, I got this. Now, how can I switch between different versions temporarily or permanently?”
If you want to switch a version only to run a quick test in the current terminal, all you need is one command. Let’s say I want to use Java 14 from AdoptJDK to test some new features, I’d run the following.
$ sdk use java 14.0.1.hs-adpt
And that’s it! Just bear in mind you need to have this version already installed.
If I check the current Java version, I get the following:
$ java --version
openjdk 14.0.1 2020-04-14
OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.1+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.1+7, mixed mode, sharing)
As soon as you close this terminal session, or open a new one, JAVA_HOME (or the default version) will be set back to what it was before.
If you’d like to permanently set a different version as default, all you need is love the following command:
$ sdk default java 14.0.1.hs-adpt
In the snippet above, I’m again setting the default version to Java 14 from AdoptJDK. This time, though, it’s being set permanently.
You can close the current terminal session, open a new one and check the current default version:
$ java --version
openjdk 14.0.1 2020-04-14
OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.1+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.1+7, mixed mode, sharing)
Or:
$ sdk current java
Using java version 14.0.1.hs-adpt
Let’s suppose you have set the default version to Java 14 but you have one specific project where you need Java 8 set. From what you’ve learned so far, every time you need to work on this Java 8 project, you need to set the current terminal to have Java 8 as a default Java implementation using sdk use
command. This process is quite annoying, to be honest, and there’s a better way to do it.
You can configure a file called .sdkmanrc
to set a specific environment for that specific folder.
In order to create this file, you need to run sdk env init
on the folder where you plan to have that specific Java version set.
After creating the file, you need to edit it and change the Java version you want to use, which in this example is Java 8, using a key/pair configuration like below:
java=8.0.252-amzn
Now, when you start working on this project, you can just run sdk env and it will set the Java version to 8 for that specific shell only and you can work on your project.
However, the whole point of this is to not have to execute any command in order to have the correct version, right?
For that to happen you need to add the following config to the SDKMAN! configuration file, which is located at ~/.sdkman/etc/config
sdkman_auto_env=true
Now you should have an environment where you switch Java version automatically without having to execute specific commands to do so.
Over time, new Java versions will be released and in order to keep up, you might want to update them. To do so, all you have to do is to run the following command:
$ sdk upgrade java
If you want do run a general upgrade, you can just run:
$ sdk upgrade
This will upgrade every tool (JDKs and SDKs) you’ve installed through SDKMAN!
Well, the same way you can easily manage Java versions with SDKMAN! you can also manage Maven and Gradle versions.
To list the available versions:
$ sdk list maven
or
$ sdk list gradle
To install a specific version:
$ sdk install maven 3.6.3
or
$ sdk install gradle 6.5.1
Also, you can manage current versions the same way shown above with Java, both temporarily or permanently.
I plan to update this post with the directives to have SDKMAN! on Windows and also with other tools available, like Spring. If you want to check other SDKs available on SDKMAN!, you can look it up on its official website.
I hope this helps you! Let me know in case you’ve got any questions.