Introduction

Java 17 was released on September 14, 2021. Java 17 is the next LTS version after Java 11. It’s expected that users of Java 11 will gradually migrate to Java 17. This book summaries all major changes from Java 11 to Java 17, so you can easily migrate from Java 11 to Java 17.

An icon indicating this blurb contains information

Spring Framework 6 is released with requirements of JDK 17+, so you have to upgrade to JDK 17 to use Spring Framework 6.

If you are currently using Java 8, then you may need to know how to upgrade from Java 8 to Java 11 first. You can check out my book Exploring Java 9 for changes in Java 9.

If you want to upgrade from Java 17 to Java 21, you can check out my book From Java 17 to Java 21.

Java Releases Schedule After Java 9

After Java 9, the Java community has adopted a new release mode. There will be a new Java release every six months, which means two releases per year. One version will be released in March, while the other version will be released in September. For example, Java 16 was released in March 2021, while Java 17 was released in September 2021.

For each release, there will be only six months support, until the next version is released. During these six months, there will be two quarterly security updates. For example, Java 15 only has the initially released version 15.0.0 and two security updates 15.0.1 and 15.0.2. After Java 16 is released, there will be no more updates for Java 15. You have to upgrade to Java 16 to get updates.

For most projects, it’s not practical to frequently update Java versions. Java also has LTS (Long-term support) versions. When using LTS versions, you can get updates for a long time. Java 8 and Java 11 are both LTS versions. Java 17 will be the next LTS version. For Java 11, you can get free public updates until at least 2024. Some companies offer free public updates for an extended period. So for most projects, LTS versions should be used.

JEPs in Different Java Releases

Java Enhancement Proposal (JEP) is used to organize changes to OpenJDK. A Java release may contain a list of JEPs. Below are lists of JEPs added in each Java release from Java 12 to Java 17.

Java 12

Java 12 has 8 JEPs, see the table below.

Figure 1. JEPs in Java 12
Number Name
189 Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)
230 Microbenchmark Suite
325 Switch Expressions (Preview)
334 JVM Constants API
340 One AArch64 Port, Not Two
341 Default CDS Archives
344 Abortable Mixed Collections for G1
346 Promptly Return Unused Committed Memory from G1

Java 13

Java 13 has 5 JEPs, see the table below.

Figure 2. JEPs in Java 13
Number Name
350 Dynamic CDS Archives
351 ZGC: Uncommit Unused Memory
353 Reimplement the Legacy Socket API
354 Switch Expressions (Preview)
355 Text Blocks (Preview)

Java 14

Java 14 has 16 JEPs, see the table below.

Figure 3. JEPs in Java 14
Number Name
305 Pattern Matching for instanceof (Preview)
343 Packaging Tool (Incubator)
345 NUMA-Aware Memory Allocation for G1
349 JFR Event Streaming
352 Non-Volatile Mapped Byte Buffers
358 Helpful NullPointerExceptions
359 Records (Preview)
361 Switch Expressions (Standard)
362 Deprecate the Solaris and SPARC Ports
363 Remove the Concurrent Mark Sweep (CMS) Garbage Collector
364 ZGC on macOS
365 ZGC on Windows
366 Deprecate the ParallelScavenge + SerialOld GC Combination
367 Remove the Pack200 Tools and API
368 Text Blocks (Second Preview)
370 Foreign-Memory Access API (Incubator)

Java 15

Java 15 has 14 JEPs, see the table below.

Figure 4. JEPs in Java 15
Number Name
339 Edwards-Curve Digital Signature Algorithm (EdDSA)
360 Sealed Classes (Preview)
371 Hidden Classes
372 Remove the Nashorn JavaScript Engine
373 Reimplement the Legacy DatagramSocket API
374 Disable and Deprecate Biased Locking
375 Pattern Matching for instanceof (Second Preview)
377 ZGC: A Scalable Low-Latency Garbage Collector
378 Text Blocks
379 Shenandoah: A Low-Pause-Time Garbage Collector
381 Remove the Solaris and SPARC Ports
383 Foreign-Memory Access API (Second Incubator)
384 Records (Second Preview)
385 Deprecate RMI Activation for Removal

Java 16

Java 16 has 17 JEPs, see the table below.

Figure 5. JEPs in Java 16
Number Name
338 Vector API (Incubator)
347 Enable C++14 Language Features
357 Migrate from Mercurial to Git
369 Migrate to GitHub
376 ZGC: Concurrent Thread-Stack Processing
380 Unix-Domain Socket Channels
386 Alpine Linux Port
387 Elastic Metaspace
388 Windows/AArch64 Port
389 Foreign Linker API (Incubator)
390 Warnings for Value-Based Classes
392 Packaging Tool
393 Foreign-Memory Access API (Third Incubator)
394 Pattern Matching for instanceof
395 Records
396 Strongly Encapsulate JDK Internals by Default
397 Sealed Classes (Second Preview)

Java 17

Java 17 has 14 JEPs, see the table below.

Figure 6. JEPs in Java 17
Number Name
306 Restore Always-Strict Floating-Point Semantics
356 Enhanced Pseudo-Random Number Generators
382 New macOS Rendering Pipeline
391 macOS/AArch64 Port
398 Deprecate the Applet API for Removal
403 Strongly Encapsulate JDK Internals
406 Pattern Matching for switch (Preview)
407 Remove RMI Activation
409 Sealed Classes
410 Remove the Experimental AOT and JIT Compiler
411 Deprecate the Security Manager for Removal
412 Foreign Function & Memory API (Incubator)
414 Vector API (Second Incubator)
415 Context-Specific Deserialization Filters

Install Java 17

You can get Java 17 binaries from several different places. Since Java 17 is a LTS version, many vendors will provide Java 17 releases. For most users, Eclipse Temurin is the best choice as it’s not vendor-specific.

  • Download OpenJDK 17 build from jdk.java.net.
  • Download Eclipse Temurin from Adoptium.
  • Use SDKMAN to install, e.g. sdk install java 17.0.16-amzn or sdk install java 17.0.16-tem.
  • Use IDE to download. IntelliJ IDEA can download JDK.

Below is the output of java -version for Eclipse Temurin 17.

Figure 7. Output of java -version
1 openjdk version "17.0.13" 2024-10-15
2 OpenJDK Runtime Environment Temurin-17.0.13+11 (build 17.0.13+11)
3 OpenJDK 64-Bit Server VM Temurin-17.0.13+11 (build 17.0.13+11, mixed mode, sharing)

Build Tools

When using Java 17 with build tools, Maven or Gradle, you may need to add the --enable-preview argument to enable preview features. The following code shows an example of the configuration of Maven compiler plugin. jdk.incubator.foreign is an incubating module, so it needs to be added explicitly using --add-modules.

Figure 8. Maven compiler plugin configuration
 1 <plugin>
 2     <groupId>org.apache.maven.plugins</groupId>
 3     <artifactId>maven-compiler-plugin</artifactId>
 4     <version>3.13.0</version>
 5     <configuration>
 6         <source>17</source>
 7         <target>17</target>
 8         <compilerArgs>
 9             <arg>--enable-preview</arg>
10             <arg>--add-modules</arg>
11             <arg>jdk.incubator.foreign</arg>
12         </compilerArgs>
13     </configuration>
14 </plugin>

Source Code

Source code of this book can be found on GitHub.