Upgrade from Java 1.8 to Java 17 | HCLTech

Upgrading from Java 1.8 to Java 17

Explore the process of upgrading Gradle-based applications from Java 1.8 to Java 17.
3 minutes read
Rani  Shinde


Rani Shinde
Senior Technical Lead
3 minutes read
Upgrading from Java 1.8 to Java 17

This blog emphasizes on the process of upgrading Gradle-based applications from Java 1.8 to Java 17.

The transition from JDK 1.8 to 17 is an important consideration as Oracle and many other vendors will cease their support to JDK 1.8 in the future. With both JDK 1.8 and 17 being LTS versions of Java, the benefit of using the LTS version lies in their stability and the frequent release of bug fixes and patches. Therefore, migrating to the latest version with long-term support is advisable for your application.

There are many new features released in JDK 17 that enhances application performance. Some of them are:

  • Changes in the just-in-time mechanism
  • Language level enhancement
  • Security-related features

Now to meet our objective of upgrading application from JDK 1.8 to JDK 17, one should take following steps:

  1. Beware of major JDK features released in each version:

    The best approach to start is by reviewing the migration guide and release documentation available on the official JDK vendor website. This illuminates the new features and modifications introduced in the latest JDK version. Below are a few of the major changes post JDK 1.8:

    1. Enhancement in garbage collection
    2. Modularity
    3. Java shell tool
    4. Strong encapsulation of JDK internals
    5. Deprecated many Java classes and packages

    And the list goes on.

  2. Evaluate your application and document possible issues post-migration:

    Upon understanding the JDK features and changes, it is crucial to evaluate the application code for potential compatibility issues post-migration. In our case, issues arose due to outdated Gradle and Groovy versions, which were incompatible with JDK 17. The initial step involved upgrading Gradle and Groovy within the application and adjusting configurations in the build.gradle file accordingly.

    Furthermore, any third-party libraries utilized in the application must be upgraded if they are incompatible with JDK 17. For example, the Spring Boot dependency version 2.3 has transitive dependencies of CGLIB and ASM. However, CGLIB may not function properly with the latest JDK version, necessitating an upgrade to the Spring Boot dependency version to ensure compatibility with JDK 17.

  3. Add dependencies for API which are deprecated in JDK releases:

    Most of the APIs were removed from each JDK version. For instance, Java Architecture for XML Binding (java.xml.bind) is removed in JDK 11 and RMI Activation is removed in JDK 17. So, if the code base utilizes such API, then either dependencies of such API should be removed or alternative dependencies must be explored to fulfill necessary requirements.

  4. Add VM arguments to access JDK internal classes:

    Most of the application code might be using JDK classes, which are now not public. As part of JDK’s strong encapsulation, Java has restricted access to those classes. But there is a workaround to use these packages:

    add VM argument --add-opens module/package=target-module

    e.g.: --add-exports java.base/sun.security.x509=ALL-UNNAMED.

    However, it is advised to remove the dependency of such packages as Java will gradually restrict complete access and the above solution will not be useful in future JDK releases.

  5. Remove use of deprecated VM parameters:

    Most of the JVM parameters have been removed by JDK which has caused an error at runtime for the applications using such parameters. To identify such parameters and remove them from your code, for, e.g., PrintGCDetails.

  6. Rewrite code that may be calling deprecated functions and classes:

    There may be pieces of code in your application that are calling deprecated functions. For example, the code might be using reflection API like below, which will not work after upgradation:

    ClassLoader callerClassLoader = Reflection.getCallerClass(3).getClassLoader();

    So, the user needs to find an alternative way or remove the dependency of such code.

Although, the above process might appear laborious, will be immensely more helpful for application performance with advanced features.

Reference Link:


Share On