Overview

In the previous post we installed SDKMAN and learned how we can use it to help us manage SDKs. This post will go over how we can make JDKs that have not been installed with SDKMAN, visible to it so they can be managed with SDKMAN. We will also uninstall a JDK, using the APT package manager once we no longer need or want it on our system.

Requirements

This guide was written and tested on Ubuntu 20.04 LTS. The SDKMAN commands should however work across all platforms. You also need to have a JDK installed; one which was not installed using SDKMAN. Don’t worry if don’t have one installed though as it will also cover how to install the latest OpenJDK LTS version using Ubuntu’s package manager. If you already have a JDK installed, then you can skip over to the next section.

Install JDK

OpenJDK 17 is the latest LTS version that is supported by Ubuntu 20.04 LTS out-of-box. That means that we can use APT, Ubuntu’s package manager, to download, install and also add the JDK to to our system’s PATH for us.

Let’s first make sure Ubuntu is up-to-date by first copying, pasting and running update and then the upgrade commands.

sudo apt update && apt upgrade

Now that everything is up-to-date, let’s install OpenJDK 17 with the following command.

sudo apt install openjdk-17-jdk

It’s a good practice to check whether a newly installed JDK works by checking the Java version at the command line. If however, you have SDKMAN installed and you have used it to install a JDK, then checking the Java version will display whatever current JDK, SDKMAN points to.

java -version

In my case running the java -version command points to Temurin version 21.0.2. What you see on your screen will depend on what JDK is installed and set as the default in SDKMAN.

openjdk version "21.0.2" 2024-01-16 LTS
OpenJDK Runtime Environment Temurin-21.0.2+13 (build 21.0.2+13-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.2+13 (build 21.0.2+13-LTS, mixed mode, sharing)

Let’s also run the equivalent command to check the version of the default Java candidate in SDKMAN.

sdk current java

We should see that it also points to Temurin 21.0.2.

Using java version 21.0.2-tem

So we have installed a JDK without using SDKMAN but we can’t access it because SDKMAN doesn’t know it even exists. Let’s now move on to the next section to find how we make SDKMAN point to OpenJDK 17.

Manage OpenJDK 17 with SDKMAN

In this section we are first going to tell SDKMAN where our newly installed JDK is located. Once that is done we’ll see how we can use OpenJDK 17 in SDKMAN in the current shell and then cover how it can be made the default version system wide.

sdk install

Here’s the command need to run to make OpenJDK 17 visible to SDKMAN.

sdk install <candidate> <version name> <path to jdk>

We have to use java for the candidate. The version name can be anything we’d like. I’ll use openjdk-17-jdk to keep things consistent with the package name that was installed in Ubuntu. The path is where the JDK is located on my computer; /usr/lib/jvm/java-17-openjdk-amd64/. If you used the apt install command to install your JDK, then it should be in the same location. If you installed another another JDK or if you installed it manually, then you need to provide the path where it is located.

sdk install java openjdk-17-jdk /usr/lib/jvm/java-17-openjdk-amd64/

If everything went well, you should see the following message printed on the screen.

Done installing!

We can also check that OpenJDK 17 now appears in the list of Java candidates.

sdk list java

We have to scroll all the way down to the bottom of the list and see openjdk-17-jdk under the “Identifier” column.

================================================================================
Available Java Versions for Linux 64bit
================================================================================
 Vendor        | Use | Version      | Dist    | Status     | Identifier
--------------------------------------------------------------------------------
 Other JDKs omitted...
 Unclassified  |     | openjdk      | none    | local only | openjdk-17-jdk

Although this example used OpenJDK 17, keep in mind that we can use this method to make SDKMAN aware of any JDK. All we need is to know where it is located.

sdk use

With SDKMAN now aware of the location of our JDK, we can run the use command to enable openjdk-17-jdk in the current shell.

sdk use java openjdk-17-jdk

We should see the following confirmation on the screen.

Using java version openjdk-17 in this shell.

We can now check the Java version to confirm OpenJDK 17 is available on our shell.

java -version

Hopefully we see OpenJDK version “17.0.9” as the current Java candidate in the current shell.

openjdk version "17.0.9" 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+9-Ubuntu-120.04)
OpenJDK 64-Bit Server VM (build 17.0.9+9-Ubuntu-120.04, mixed mode, sharing)

That’s great, SDKMAN is now pointing to openjdk-17-jdk! We can now manage other JDKs which are not installed with SDKMAN. Remember that by running the use command we can only access openjdk-17-jdk within the terminal shell in which we ran that command. If we open another shell, then the default Java candidate will be active.

Next we’ll go over how we can make SDKMAN use openjdk-17-jdk across our entire system including any new shells we may open up and any other program which points to Java using the JAVA_HOME environment variable.

sdk default

Let’s start out by confirming which JDK SDKMAN currently uses system wide.

sdk current java

I’m seeing Temurin 21.0.2 but you will see whichever JDK is set as the default in SDKMAN for your system.

Using java version 21.0.2-tem

In order to set OpenJDK 17 as the default version we need to run the following command.

sdk default java openjdk-17-jdk

SDKMAN’s confirmation makes it very clear that that OpenJDK 17 should now be set for all shells.

setting java openjdk-17-jdk as the default version for all shells.

If we run java -version now, we should see that OpenJDK 17 is the current Java candidate, even if we open up a brand new shell.

In the last section of this guide we are going to uninstall OpenJDK 17 using APT.

Uninstall JDK

Before we uninstall OpenJDK 17, we should switch the default Java candidate in SDKMAN to a different JDK. This is just a precaution as I’m not sure how SDK handles deleting the current JDK and I don’t want to cause any problems with my system.

sdk default java 21.0.2-tem

Let’s use the dpkg to list all packages which are currently installed in our system. We can also use grep to highlight only packages which contain jdk in the package name.

dpkg --list | grep jdk

The “Version” and “Architecture” columns have been removed from the output of the dpkg --list command so the content fits on one line.

    Name                            Description
+++-===============================-=======================================
ii  openjdk-17-jdk:amd64            OpenJDK Development Kit (JDK)
ii  openjdk-17-jdk-headless:amd64   OpenJDK Development Kit (JDK) (headless)
ii  openjdk-17-jre:amd64            OpenJDK Java runtime, using Hotspot JIT
ii  openjdk-17-jre-headless:amd64   OpenJDK Java runtime, using Hotspot JIT (headless)

We have to make sure we remove all four packages.

sudo apt purge --auto-remove openjdk-17*

Type y and press Enter to uninstall the packages and remove the files.

Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'openjdk-17-jdk-headless' for glob 'openjdk-17*'
Note, selecting 'openjdk-17-jre-headless' for glob 'openjdk-17*'
Note, selecting 'openjdk-17-dbg' for glob 'openjdk-17*'
Note, selecting 'openjdk-17-doc' for glob 'openjdk-17*'
Note, selecting 'openjdk-17-jdk' for glob 'openjdk-17*'
Note, selecting 'openjdk-17-jre' for glob 'openjdk-17*'
Note, selecting 'openjdk-17-source' for glob 'openjdk-17*'
Note, selecting 'openjdk-17-demo' for glob 'openjdk-17*'
Note, selecting 'openjdk-17-jre-zero' for glob 'openjdk-17*'
Package 'openjdk-17-dbg' is not installed, so not removed
Package 'openjdk-17-demo' is not installed, so not removed
Package 'openjdk-17-doc' is not installed, so not removed
Package 'openjdk-17-jre-zero' is not installed, so not removed
Package 'openjdk-17-source' is not installed, so not removed
The following packages will be REMOVED:
  ca-certificates-java* fonts-dejavu-extra* libatk-wrapper-java*
  libatk-wrapper-java-jni* libxt-dev* openjdk-17-jdk*
  openjdk-17-jdk-headless* openjdk-17-jre*
  openjdk-17-jre-headless*
0 upgraded, 0 newly installed, 9 to remove and 23 not upgraded.
After this operation, 284 MB disk space will be freed.
Do you want to continue? [Y/n]

If we list all packages which are currentyl installed and have jdk in the name again, we won’t see any output.

dpkg --list | grep jdk

Main Takeaways

  1. We can install JDKs which are not available in SDKMAN but they will not be accessible in our operating System.
  2. We need to make SDKMAN aware of their location using the install command.
  3. Once SDKMAN knows where a JDK is located, we can manage it with either the use or default commands.