With a new Java version being released every six months and the next LTS (Long Term Support) version 17 standing on our doorstep (September 2021), staying up-to-date with new language features is both important and easy. This post describes my simple setup that allows working & experimenting with different Java versions, using Ubuntu and Eclipse IDE.

Installation as Ubuntu / Debian packages

Depending on the Ubuntu version, certain JDK versions can be installed through the package manager APT. Examples:

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

This installs the given JDKs to subdirectories of /usr/lib/jvm/. The advantage of this kind of installation is that it automatically takes care of future security updates, and integration into the command line path.

To display the currently active JDK version:

java -version

To switch between these versions:

update-alternatives --config java

However, I hardly ever switch between Java versions on this level. Instead, I always have the most recent LTS version configured.

Installation as compressed archive

Non-LTS versions may take a while until they become available as Ubuntu package (depending on the Ubuntu version). These Java versions can be downloaded directly from different vendors, such as Oracle (https://jdk.java.net/, which also provides early-access builds). After extraction of the tar.gz archive (e.g., to /opt/java/jdk-16.0.1), the JDK is ready to use. To make it available in the current shell session:

export PATH="/opt/java/jdk-16.0.1/bin/:$PATH"

IDE Configuration

Using new language features (such as records) requires a current IDE version, and perhaps certain extensions. At the time of writing, Eclipse IDE 2021-03 provides “Java 16 Support” via its marketplace.

My Eclipse IDE itself runs on the current LTS version provided by the OS package above, and the default “Compiler compliance level” is set to the same version under “Window / Preferences / Java / Compiler”. Additional versions must be added under “Window / Preferences / Java / Installed JREs”.

The desired Java release version for a project is specified in its POM:

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <release>11</release>
        </configuration>
      </plugin>
    </plugins>
  </build>

These settings are picked up by the Eclipse-specific project metadata by right-clicking on the project and choosing “Maven / Update Project”. This way, the IDE automatically uses the right JDK for building this project.

Why not only have the most recent Java version installed?

Because you might want to

  • use the same version on your workstation that is deployed in production
  • play with early access versions that are not yet recommended for general use

One reason for having different JDKs installed has been eliminated with JEP 247, which introduced the release compiler option mentioned above. When having only the newest Java version installed and configuring a lower Java version with

  <properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  </properties>

instead of using the release option, you might accidentally invoke new APIs that are not available in this earlier version (such as Stream.toList(), which has been added in Java 16).

With the release option, the compiler will raise an error at build time if you use newer APIs.