Posts

Migration from Java 11 to Java 17

Jul 13, 2023
Dmitry Chuyko
14.2

The Java platform is getting more powerful with every release. Migration from Java 11 to Java 17 will bring significant improvements in performance, security, and cloud-native capabilities of your Java-based workloads. With modern garbage collectors and new and updated APIs increasing security and facilitating code writing and maintenance, Java 17 is an essential upgrade for projects looking to stay competitive.

This guide provides a step-by-step approach to ensure a smooth transition and highlights common pitfalls to avoid.

Key reasons to upgrade from Java 11 to Java 17

JDK 11 is a legacy LTS release. It is in maintenance mode meaning that only few improvements are backported to this branch. As a result, the performance of JDK-11 based workloads doesn’t meet the requirements for modern software.

But what exactly do we mean by improvements in Java 17? They are:

  • Enhanced Garbage Collection: improved G1 GC, production-ready low-latency collectors ZGC and Shenandoah GC.
  • Better security: Strong encapsulation of JDK internals (JEP 403) forbids using the internal components of the JDK, thus increasing the security of the Java platform and maintainability of the Java applications.
  • New features: Java 17 includes 
    • The Foreign Function & Memory API (JEP 412) to interoperate with code and data outside of the Java runtime without the risks of JNI,
    • Context-Specific Deserialization Filters (JEP 415) to configure the deserialization filters via a JVM-wide filter factory,
    • Pattern matching for switch (JEP 406) to express data-oriented queries concisely and safely,
    • Sealed classes (JEP 409) for better control over the code responsible for implementing the classes developers create.
  • Better containerization: Optimizations  for running Java in containers, including resource management improvements.

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 and follow the instructions to complete the installation. 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:

FROM bellsoft/liberica-runtime-container:jre-17-stream-musl

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.

Java 11 to Java 17 comparison

The table below summarizes key differences between Java 11 and Java 17 in terms of performance-specific JVM features and support period.

 

 

Java 17

Java 11

Garbage Collectors

Improved G1 GC, Parallel GC, Serial GC

G1 GC, Parallel GC, Serial GC, CMS GC

Low-latency Garbage Collectors

ZGC, Shenandoah GC*

ZGC (Experimental), Shenandoah GC (since 11.0.9)

CDS

Dynamic AppCDS

AppCDS

Access to JDK internals

Strong encapsulation (JEP 403)

Possible with the --illegal-access flag

Number of Intrinsics (x86_64)

107

98

End of commercial support for Oracle Java SE 

2029

2026

End of free public updates for Oracle Java SE

2022

2019

End of commercial support for Liberica JDK

2030

2032

End of free public updates for Liberica JDK

2030

2032

*Oracle Java doesn't include Shenandoah GC, but it is available with major OpenJDK distributions, including Liberica JDK.


For more details on the support terms consult Liberica JDK Support Roadmap.

Common migration issues

Migration from Java 11 to Java 17 can be associated with a few challenges related to the removed components and APIs and strong encapsulation of JDK internals. Here’s what you should consider.

Removed 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.

Discontinued components

The following tools have been removed from the JDK since Java 11, and if your code depends on them, it will require code modifications or migration to alternative solutions:

  • The Applet API: Applets were removed as no modern browser supports them anymore. If your code uses applets, replace them with modern web technologies such as HTML5 or JavaScript-based solutions.
  • The Security Manager: This API has been marked for removal. Consider adopting alternative sandboxing tools.
  • The Remote Method Invocation (RMI) Activation: The RMI Activation has been removed, so you have to migrate to more robust distributed computing frameworks like gRPC.
  • The Experimental Features AOT and Graal JIT: These features are now part of the standalone open-source GraalVM Project.
  • The Concurrent Mark Sweep (CMS) Garbage Collector: The CMS GC has been deprecated and removed in favor of G1 GC. You can also try out low-latency garbage collectors ZGC or Shenandoah GC.

Managing removed APIs

There were a few APIs removed from the JDK since version 11. To identify affected areas in your code, utilize the jdeprscan tool to search for usage of deprecated or eliminated APIs. 

If the scan reveals dependencies on removed APIs, you can:

  • Add related dependencies if the missing modules are now maintained as separate open-source libraries.
  • Rewrite affected code using modern standard APIs.

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, you should:

  • Use standard APIs instead of internal ones.
  • 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.
  • As a temporary workaround, you can use the --add-exports and --add-opens options.  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. 

GraalVM and Native Image compilation

If your application relied on the experimental AOT or Graal JIT features in Java 11, consider transitioning to GraalVM. GraalVM is a JDK and JVM written in Java that also offers Ahead-of-time compilation for fast startup times and reduced memory usage.

Several distributions of GraalVM are available: Oracle GraalVM and GraalVM Community edition with two downstream versions, Liberica Native Image Kit and Mandrel. Liberica NIK is recommended as a native-image compiler by Spring, so you can use it with your Spring applications to achieve faster startup and peak performance without warmup.

Recommendations for smooth migration

To ensure a smooth transition from Java 11 to Java 17:

  • Test your application in a special set up testing environment with the updated JDK.
  • Review and update all dependencies and build tools to versions compatible with JDK 17.
  • Resolve any issues that arise after you have started your application.
  • Identify dependence on removed APIs  using jdeprscan and rewrite the code accordingly.
  • Identify libraries that depend on internal APIs using jdeps and update them or use alternative solutions.

With proper planning, you can efficiently address these challenges, allowing your project to leverage the performance, security, and modern features of Java 17.

How to stay on Java 11 and get all Java 17 perks?

If you are not ready for a full-fledged migration to Java 17, but want its performance improvements, consider Liberica JDK Performance Edition. This innovative solution that couples JDK 11 and JVM 17 enables you to:

  • Boost performance. Achieve up to a 15% increase in startup times and lower latency.
  • Preserve compatibility. Get the benefits of JVM 17 while maintaining your JDK 11-based infrastructure.
  • Upgrade at your own pace.  Upgrade less critical services first, leveraging the advantages of modern Java performance for critical services.

 

Subcribe to our newsletter

figure

Read the industry news, receive solutions to your problems, and find the ways to save money.

Further reading