Every Java release contains new features and enhancements boosting the JVM performance, facilitating code writing, and increasing application security.
Luckily, the process of upgrading Java version from 11 to 17 is not that complicated as in case of Java 8, but there are some nuances you should keep in mind to ensure smooth migration.
Table of Contents
Upgrade Java version, dependencies, and tools
First of all, change the Java version for your project.
Download the binary with the latest release of Java 17. You can also use package managers (SDKMAN, Brew, etc.) or Linux repositories to install the JDK on your machine. For instance, to pull Liberica JDK 17 from a Yum repository, run
sudo yum update sudo yum install bellsoft-java17
After that, change the JDK version in your IDE and build tools (Maven, Gradle).
If you use Docker images, update your Dockerfile as well. For instance, to move your application into a microcontainer with Liberica JDK and Alpaquita Linux, specify:
Note: you can use a glibc-based Alpaquita version if required for compatibility with the previous Linux distribution.
Now, update all tools, libraries, and third-party dependencies to versions that support JDK 17. The framework and its dependencies should also work with version 17. For example, here are the latest versions of common technologies used in Java development that support JDK 17:
- IntelliJ IDEA 2021.2.1
- Eclipse: 2021-09 (4.21)
- Maven: 3.8.1
- Gradle: 7.3
- Spring Boot: 2.5
- Lombok: 1.18
Naturally, the list goes on, but you get the idea.
After all the updates, compile and run your application and run the tests. Solve the remaining issues based on the error messages you see (if any). Some possible problems are described in the sections below.
Which Java distribution should you use?
The question arises if you find yourself in one of the following situations:
- You use Oracle Java and are dissatisfied with regular licensing changes or unwilling to pay for costly Java support according to the new Employee for Java SE Universal Subscription;
- You use Java distributions from several vendors and would like to unify the stack and lower the support expenses;
- You implement a free JDK build without support and would like to secure your project.
Firstly, if you run your workloads in Oracle Java, it is possible to migrate from Oracle to OpenJDK whose developers provide just as performant and secure runtimes. Secondly, you can use one runtime for all your platforms and purposes and receive affordable 24/7 services directly from experienced Java engineers. The key is to select a Java distribution with all features you need and cost-efficient support. Take a look at the Java alternatives overview with a comparison of the most popular Java distributions. Find out about their benefits, features, additional instruments, and supported system configurations, and make an informed decision.
Those of you who are looking for a reliable vendor, can download a comparison of commercial offerings provided by OpenJDK vendors, so that you have a clear understanding of the value you get for your money.
Common migration issues
Removed components and JVM options
Several JVM parameters were removed or deprecated up to Java 17. While obsolete or deprecated options make the program produce a warning without affecting its operation, the usage of removed ones will cause the JVM to exit with
Error: Could not create the Java Virtual Machine. The solution is to abstain from using the no longer valid parameters.
In addition, some tools have also been taken out of JDK since Java 11, including:
- The Applet API,
- The Security Manager,
- The Remote Method Invocation (RMI) Activation,
- The Experimental Features AOT and Graal JIT,
- The Concurrent Mark Sweep (CMS) Garbage Collector.
If your project depends on any removed components, you will have to rewrite it accordingly. For some features, there are alternatives. For example, instead of CMS GC, you can use a more modern low-latency garbage collector implementation such as G1 GC or Shenandoah GC.
GraalVM is now developed as a separate open-source project with builds available for JDK 17 and the current version. If you lack only the AOT mode, take a look at Liberica Native Image Kit, a default native-image compiler in Spring Native. It is based on GraalVM Open Source and recently got a new experimental Parallel GC (GraalVM CE currently has only Serial GC, and Oracle GraalVM also offers G1 GC). After receiving feedback from the community, it will be integrated into the upstream project to reduce the latency in Java native images.
There were a few APIs removed from the JDK since version 11. Utilize the jdeprscan tool to search for deprecated or eliminated APIs, and then add related dependencies if the missing modules are available in the open source, or rewrite the code.
Strong encapsulation of JDK internals
One of the JDK 17 features that may affect the migration process is strong encapsulation of JDK internals (JEP 403), whose goal is to make JDK more maintainable and secure. The reflective access to the low-level JDK APIs was restricted in Java 9, but versions 9–16 allowed the developers to use --illegal-access option as a workaround. In Java 17, this parameter is no longer valid and the application will throw the java.lang.reflect.InaccessibleObjectException.
To solve the issue, use standard APIs instead of internal ones and update libraries to the latest versions that don’t access JDK internals. The jdeps tool with a --jdk-internals option will help you pinpoint problematic libraries by listing class-level dependencies in the JDK internal APIs.
There are two options that help to bypass the restraint:
--add-opens. But remember that using these tools compromises the security of your applications, so resort to them only in case of emergency and for a short term while you are rewriting the code.
How to stay on Java 11 and get all Java 17 perks?
What if you want to benefit from enhanced performance and new features of Java 17, but aren’t ready for a full-fledged migration yet? The BellSoft engineers developed a solution that brings the power of JVM 17 to your JDK 11-based project with little to no code adjustments, Liberica JDK Performance Edition!
Liberica JDK Performance Edition brings instant improvement to startup, throughput, and latency even at the default settings.