Migrating from Java 8 to Java 11 or Java 17

Migrating from Java 8 to Java 11 or Java 17

We are in an era of constant change, tech is evolving at a fast pace that its had never happened before in the previous decade.

By the end of this decade 2030, we will be entering the era of space software.

According to Oracle, more than 55 billion devices run on Java. All these trillions of line of code is written in one of these Java version which was released in the years.

So, in this, we will cover how and why need to start the upgrade of your application on the latest Java version released for LTS. And the strategies too.

There are two basic things or strategies you want to choose from because Java 8, 11, and 17 are all our LTS, so let us see :

  1. Migrating from Java 8 to Java 17 or
  2. Migrating from Java 8 to Java 11 and then to Java 17

Here, the end goal is that Java 21(as known LTS) will be released on September 23. So if we are at Java 17 then it's easier for your company to upgrade to Java 21 and so on.

I would suggest that going with approach 2 is better compared to 1. But, I leave that to your company strategy.

However, there are some concerns when you are upgrading, such as:

  • What is the impact if not upgraded?
  • How many man-days are required for this migration activity? Because man days convert to $$? ??
  • Can we wait for next year?

There are many excuses if you want to delay this activity. However, let us focus on the steps or planning that if you want to do it then what you need to do or from where you should start.


The purpose of this is to help you to migrate your existing Java applications to Java 17.

Before migrating your application to Java 17, you need to understand the changes and the features introduced in each version. Here we are migrating from Java 8 (JDK 8) to Java 17 (JDK 17).

The modularization of the Java SE Platform in JDK 9 and later provided numerous benefits, but it also brought significant modifications.?Code that exclusively uses approved Java SE Platform APIs and supported JDK-specific APIs should continue to function normally. Code that uses JDK-internal APIs should be kept running but migrated to use the supported APIs. Some APIs have been withdrawn, made inaccessible, or had their default behavior changed. When compiling or running your application, you could run into problems. Therefore, below are points to remember:

  • JDK 9-16 allowed this reflective access but warned about it. JDK 17 now enforces stronger encapsulation, blocking unauthorized reflection on non-public fields/methods.
  • The "--illegal-access" option in the Java launcher permitted reflective access in earlier JDK versions with different modes: permit, warn, debug, and deny.
  • Many tools/libraries updated to use standard Java APIs, rendering the "--illegal-access" option obsolete in JDK 17, only issuing warnings if used.
  • If newer tool/library versions aren't feasible, "--add-exports" allows runtime/compile access to encapsulated internal APIs, and "--add-opens" allows reflection into non-public Java.* APIs.
  • JDK 17's stricter encapsulation emphasizes updates for codebases and presents "--add-exports" and "--add-opens" as solutions for older tools/libraries.
  • The sun. misc and sun. reflect packages are available for reflection by tools and libraries in all JDK releases, including JDK 17.

The classpath code will fail if it tries to access non-public fields and methods of Java.* APIs by using the reflection API's setAccessible(true) method. This is not by default allowed in JDK 17. However, you can enable this with the --add-opens option. For more details, refer to the --add-opens section.?

Code that accesses non-public fields(private fields ) and methods of Java.* APIs will throw an InaccessibleObjectException.?

If you examine the file system after installing the JDK(>9), you'll see that it has a different directory structure than earlier JDK releases.

JDK 11 and later do not have the JRE image. See Installed Directory Structure of JDK in Java Platform, Standard Edition Installation Guide.?

The java.util.regex.Pattern class defines character classes in regular expressions with square brackets. For example, [abc] matches a,b, or c. Negated character classes are defined with a caret immediately following the opening square brace. For example, [^abc] matches any character except a,b, or c. In JDK 8 and earlier, negated character classes did not negate nested character classes. For example, [^a-b[c-d]e-f] matches c but does not match a or e as they are not within the nested class.


The operators are applied one after another. In this example, the negation operator ^ is applied before nesting. In JDK 8 and earlier, the operator ^ was applied only to the outermost characters in the character class but not to nested character classes. This behavior was confusing and difficult to understand.

All these changes need to be considered from Java 8, 9, 10, 11... 17. This is why it's necessary to upgrade it on a regular basis.

However, in JDK 9 and later, the negation operator was applied to all nested character classes. For example, [^a-b[c-d]e-f] does not match c. To explain further, consider the following regular expression: [^a-d&&c-f] In JDK 8, the ^ operator is applied first, hence this example is interpreted as [^a-d] intersected with [c-f]. This matches e and f but not a, b, c, or d. In JDK 9 and later, the && operator is applied first, hence this example is interpreted as the complement of [a-d]&&[c-f]. This matches a, b, e, and f but not c or d. As a best practice, look for regular expressions that use character classes with some combination of negation, intersection, and nested classes. These regular expressions may need to be adjusted to account for the changed behavior.

There are two tools which play a very important role, I will cover that in my next letter.

There are so many things to be covered. I will continue that and keep appending this soon. Thanks for reading.


要查看或添加评论,请登录

Rachit Mehrotra的更多文章

社区洞察

其他会员也浏览了