DEV Community

Atem Nkengasong
Atem Nkengasong

Posted on

Manage multiple Java versions on Linux

1. Introduction

In 2017 Oracle announced Java's (then new) six months release cadence. This was a significant change from Java’s previous cycle of one large release every two to three years. With more releases, Java is providing developers with more innovations and making the platform even more attractive. This also means that it is more complicated to manage the different versions if you want to keep up with the new features or if your different projects require different versions. In this blog post, we'll see how to manage multiple Java versions on Linux using jEnv.

2. What is jEnv ?

jEnv is a command line tool that helps to manage several Java installations. This way developers can hopefully forget how to set the JAVA_HOME environment variable. With jEnv you can setup local Java installations on global, directory and even shell level. This is possible because jEnv stores the local Java version in a .java-version file and depending on the context, will simply direct to the corresponding installation file.

3. Installation

We will start by installing some JDK versions so that we have versions to manage. We will also need Git to be able to install jEnv.

Install Java SE 8 and Java SE 11

$ sudo apt install openjdk-8-jdk && sudo apt install openjdk-11-jdk 

Install Git

$ sudo apt install git

To install jEnv we start by cloning its git repository

$ git clone https://github.com/gcuisinier/jenv.git ~/.jenv

Next we add it to our Bash Shell

$ echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(jenv init -)"' >> ~/.bash_profile
$ source .bash_profile

If the above commands do not work for you don't worry, just use .bashrc instead

$ echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(jenv init -)"' >> ~/.bashrc
$ source .bashrc

The first command above adds jEnv to your PATH so that its binaries can be found. The second simply initializes jEnv once your shell loads and source is a bash shell built-in command that executes the content of the file.

4. Usage

If you run jenv you should get the following

$ jenv
 jenv 0.5.2-28-g3f3e517
 Usage: jenv <command> [<args>]

 Some useful jenv commands are:
    commands    List all available jenv commands
    local       Set or show the local application-specific Java version
    global      Set or show the global Java version
    shell       Set or show the shell-specific Java version
    rehash      Rehash jenv shims (run this after installing executables)
    version     Show the current Java version and its origin
    versions    List all Java versions available to jenv
    which       Display the full path to an executable
    whence      List all Java versions that contain the given executable
    add         Add JDK into jenv. A alias name will be generated by parsing "java -version"

 See `jenv help <command>' for information on a specific command.
 For full documentation, see: https://github.com/jenv/jenv/blob/master/README.md

Now let's add the different JDK versions we installed to our command line tool

$ jenv add /usr/lib/jvm/java-1.8.0-openjdk-amd64    
$ jenv add /usr/lib/jvm/java-11-openjdk-amd64

To see which versions our tool can manage, execute

$ jenv versions
 system
 11
 11.0
 11.0.4
*1.8 (set by /home/nkengasong/.jenv/version)
 1.8.0.222
 openjdk64-11.0.4
 openjdk64-1.8.0.222

Hopefully you can see something similar too. Also notice the different 11s and 1.8.0s, they are just aliases referring to the same version - so you actually have two versions being managed.

Now you can specify which version you want to use. For example, if you want to use Java 11 globally use the following command

$ jenv global 11

You can work on a JDK 8 project, without changing your global version.

$ mkdir my-jdk-8-project
$ cd my-jdk-8-project
$ jenv local 1.8

If you check the Java version in your my-jdk-8-project directory you will obtain the following

$ java -version
 openjdk version "1.8.0_222"
 OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~18.04.1-b10)
 OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)

Finally we have to set the $JAVA_HOME because jEnv won't do that for us unfortunately. This is very important given that several tools like IDEs depend on this variable. To do so, we enable the export plugin as follows

$ jenv enable-plugin export

We can now verify that the $JAVA_HOME variable is set to the global Java version

$ echo $JAVA_HOME
 /home/nkengasong/.jenv/versions/1.8

You can also enable other plugins like the maven and gradle plugins

$ jenv enable-plugin maven
$ jenv enable-plugin gradle

5. Conclusion

In this blog post, we saw how to manage multiple Java versions on Linux using jEnv - a command line tool to help you forget how to set the JAVA_HOME environment variable.

Top comments (5)

Collapse
 
mateuszjarzyna profile image
Mateusz Jarzyna

I'm using SDKMAN!, it works well. I think (I don't use jEnv) it supports more JVM languages.

And because I'm using more programming languages like Erlang (and Kerl to manage versions) I'm thinking about asdf to use one tool.

Collapse
 
awwsmm profile image
Andrew (he/him)

+1 for SDKMAN! Changed my life. It's stupid easy to download and switch versions of Java, Scala, Gradle, Kotlin, sbt, Maven, ...

Collapse
 
awwsmm profile image
Andrew (he/him)

(I used to use jEnv, too, until I discovered SDKMAN! I haven't once regretted switching.)

Collapse
 
nkengasong_atem profile image
Atem Nkengasong

That's great! Thank you for sharing, I didn't know of asdf. I would try it out

Collapse
 
kadonwills profile image
Kadon • Edited

Geat, thanks i'll finally get rid of swapping java env variable per active projects. Thanks !