Search

October 16, 2020

Automatic Switching Of Java Versions With SDKMAN!

SDKMAN! is a very useful tool to manage versions of so-called software development kits. There are a lot of SDKs supported by SDKMAN!: Java, Groovy, Kotlin, Scala, Gradle, Maven, Leiningen, Micronaut, Grails, Vert.x, JBake, AsciidoctorJ and more. When we look at Java we can use a simple install java <version> command from the command-line to install a version of Java on our computer. SDKMAN! will take care of downloading the Java version and setting all the correct system variables to use that Java version. With the use command we can switch between version in the current shell we are working in. But we can even automatically switch to a specific installed Java version when we enter a directory. This is very useful when we have to work on multiple projects on our computer and each project requires a specific Java version to be used.

To support automatic switching of a Java version we must first run the env init command in the directory of our project. This creates a new file .sdkmanrc in the directory. The file contains the Java version that was active when we invoked the env init command. It is a text file so we can change the Java version in the file, or regenerate the file by running the env init command again, but with a different active Java version.

In the following shell output we have a Java 15 version set as default. We first change it to Java 11 and then run env init to set Java 11 as default version for our projec directory:

project-dir $ java -version
openjdk version "15" 2020-09-15
OpenJDK Runtime Environment AdoptOpenJDK (build 15+36)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.22.0, JRE 15 Mac OS X amd64-64-Bit Compressed References 20200922_45 (JIT enabled, AOT enabled)
OpenJ9   - 1830b1927
OMR      - 73d5e7623
JCL      - 7e7613c015 based on jdk-15+36)
project-dir $ sdk use java 11.0.8.hs-adpt

Using java version 11.0.8.hs-adpt in this shell.
project-dir $ java -version
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)
project-dir $ sdk env init
.sdkmanrc created.
project-dir $ cat .sdkmanrc
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=11.0.8.hs-adpt
project-dir $

When a directory contains the .sdkmanrc file we can use the SKDMAN! env command and SDKMAN! will set the Java version based on the contents of the .sdkmanrc file. This is already useful, because we simply go to our project directory, invoke the env command and the Java version is set to the version we expect for our poject.

In the next example we start with Java 15 as default version, next we run the env command in the directory with the .sdkmanrc file:

~ $ java -version
openjdk version "15" 2020-09-15
OpenJDK Runtime Environment AdoptOpenJDK (build 15+36)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.22.0, JRE 15 Mac OS X amd64-64-Bit Compressed References 20200922_45 (JIT enabled, AOT enabled)
OpenJ9   - 1830b1927
OMR      - 73d5e7623
JCL      - 7e7613c015 based on jdk-15+36
~ $ cd project-dir
project-dir $ sdk env

Using java version 11.0.8.hs-adpt in this shell.
project-dir $ java -version
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)
project-dir $

By changing a setting in the SDKMAN! configuration we can even let SDKMAN! run the env command when we change to our project directory in our shell. The default location of the configuration file is $HOME/.sdkman/etc/config and we must add the following line sdkman_auto_env=true. With this option we can simply change to our project directory and the correct Java version is set to active.

In our final example we have enabled the setting sdkman_auto_env, so when we change to the project directory the correct Java version is activated automatically:

~ $ java -version
openjdk version "15" 2020-09-15
OpenJDK Runtime Environment AdoptOpenJDK (build 15+36)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.22.0, JRE 15 Mac OS X amd64-64-Bit Compressed References 20200922_45 (JIT enabled, AOT enabled)
OpenJ9   - 1830b1927
OMR      - 73d5e7623
JCL      - 7e7613c015 based on jdk-15+36
~ $ cd project-dir

Using java version 11.0.8.hs-adpt in this shell.
project-dir $ java -version
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)
project-dir $

Wrtten with SDKMAN 5.9.1+575.