Manage multiple Java versions on Linux
Tags: java, productivity, linux
Published: 2020-06-11 10:54:22

---
title: "Manage multiple Java versions on Linux"
published: true
description: 
tags: [java,productivity,linux]
//cover_image: https://direct_url_to_image.jpg
---

## 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**](https://www.jenv.be/).

## 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**](https://git-scm.com/) to be able to install jEnv. 

Install `Java SE 8` and `Java SE 11`
``` console
$ sudo apt install openjdk-8-jdk && sudo apt install openjdk-11-jdk 
```

Install `Git`
``` console
$ sudo apt install git
```

To install `jEnv` we start by cloning its git repository
``` console
$ git clone https://github.com/gcuisinier/jenv.git ~/.jenv
```

Next we add it to our `Bash Shell` 
``` console
$ 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
``` console
$ 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
``` console
$ 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
``` console
$ 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
``` console
$ 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
``` console
$ jenv global 11
```

You can work on a JDK 8 project, without changing your global version.
``` console
$ 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
``` console
$ 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 <kbd>export</kbd> plugin as follows
``` console
$ jenv enable-plugin export
```
We can now verify that the `$JAVA_HOME` variable is set to the global Java version
``` console
$ echo $JAVA_HOME
 /home/nkengasong/.jenv/versions/1.8
```

You can also enable other plugins like the <kbd>maven</kbd> and <kbd>gradle</kbd> plugins
``` console
$ 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.