JAVA Why To Upgrade? -Part 1

Lalit Chaturvedi
9 min readJun 26, 2023

Background

Spring6 and SpringBoot3 launched in 2022. Before that, no matter how many new versions came out, most people were unwilling to upgrade and stuck to Java 8. This time, Spring came up with a big move. The lowest dependency of SpringBoot3 and Spring6 is JDK17! It skips JDK 8–16 and upgrades directly to JDK 17. So, why JDK 17?

Why JDK17?

There are so many new versions of JDK. Why did Spring choose JDK 17?

The main reason is that it is a commercially free LTS version announced by Oracle. LTS means Long Term Support, which is officially guaranteed to be supported for a long time.

The preceding figure shows the timeline of Oracle JDK support. As you can see, JDK 17 will be supported up to September 2029. According to the speed of technology update iteration, free commercial use for eight years is a good intention, so users can safely upgrade JDK to JDK 17. (Also, JDK 8 will be supported for a longer period that can be extended to December 2030.)

Since the creation of JDK, JDK 7, JDK 8, JDK 11, and JDK 1 have been supported long-term. JDK 17 will be the most important LTS version since Java8. It is the result of eight years of efforts by the Java community.

Java8 has been the pain point in the Java community. Java8 provides many features, such as Lambda expression and Optional class. Also, Java8 has a long support time. These are the reasons why it can be used as yet. It represents a tug-of-war between stability-oriented corporate management and developers that embrace changes. No upgrades! It becomes the tacit choice of major companies. Now, that balance may be broken. Java’s dominant framework, SpringBoot chooses the smallest supported Java LTS version, which is the latest Java17.

So, let’s see, from JDK8 to JDK17, what are the results of the Java community’s eight years of hard work?

New Features from JDK8 to JDK17

New Features of JDK9 (September 2017)

  • Modular
  • Factory methods are provided, such as List.of(), Set.of(), Map.of(), and Map.ofEntries().
  • Interfaces support private methods.
  • Optional Class Improvements
  • JAR Packages Compatible with Multiple Versions
  • JShell Tool
  • Improvement of Try-with-resources
  • Improvements to the Stream API
  • Set G1 as the JVM default garbage collector
  • APIs that support HTTP2.0 and WebSocket

Its important features are mainly API optimization (such as Client API supporting HTTP2) and JVM using G1 as the default garbage collector.

New Features of JDK10 (March 2018)

  • Local variable type inference, similar to JS, can use var to modify local variables. After compilation, the true type of the value is inferred.
  • Improvements to Immutable Collections
  • Parallel Full Garbage Collector G1 to Optimize G1 Latency
  • Thread local handshake allows thread callbacks to be executed without executing a global VM safe point. A single thread can be stopped.
  • New orElseThrow() method in Optional
  • Class Data Sharing
  • Unicode Language Label Extension
  • Root Certificates

Its important features are local variable type inference is realized through the var keyword, making Java language a weak type language and G1 garbage collection of JVM changing from single thread to multi-thread parallel processing, thus reducing G1 pause time.

New Features of JDK11 (September 2018) (LTS Version)

  • Add some string processing methods
  • Local Variable Syntax for Lambda Parameters
  • HTTP Client Rewrite supports HTTP/1.1, HTTP/2, and WebSockets.
  • Run a single Java source code file, such as java Test.java
  • ZGC: Scalable and low-latency garbage collector. ZGC can be seen as a more fine-grained memory management strategy than G1. Since the continuous allocation and recycling of the memory will generate a large amount of memory fragmentation space, a defragmentation policy is required. The thread for memory reference needs to be logically suspended during defragmentation. This process is called Stop the world. The thread logic can only continue to run when the process is complete. (Parallel Reclaim)
  • Support for TLS 1.3 Protocol
  • Flight Recorder, a Data Collection Framework for OS, JVM, and a JDK-based Event
  • Enhancements to the Stream, Optional, and Collection APIs

Its important features are improvements for JDK9 and JDK10, mainly for stream, collection, and other APIs and a new ZGC garbage collector.

New Features of JDK12 (March 2019)

  • Switch expression extension with a return value
  • Add NumberFormat to format complex numbers
  • Character strings support the transform and indent operations
  • Add Method Files.mismatch (Path, Path)
  • Teeing Collector
  • Support for Unicode 11
  • Shenandoah GC, New GC Algorithm
  • The optimization of the G1 collector divides the garbage of the GC into a mandatory and an optional part. The mandatory part will be recycled, while the optional part may not be recycled, improving the efficiency of the GC.

Its important features are the switch expression syntax extension, G1 collector optimization, and new Shenandoah GC garbage collection algorithm.

New Features of JDK13 (September 2019)

  • The switch expression is extended. The switch expression adds the yield keyword to return the result. The function is similar to return. If no result is returned, break is used.
  • Text blocks are upgraded to “””. It introduced text blocks. You can use three double quotation marks (“””) to indicate text blocks. You do not need to use line break escape characters inside text blocks.
  • SocketAPI refactoring, the underlying implementation of Socket is optimized, and NIO is introduced.
  • FileSystems.newFileSystem New Method
  • ZGC is optimized to enhance ZGC to release unused memory and return the in-heap memory space marked as idle for a long time to the operating system. It aims to ensure that the heap size is not less than the configured minimum heap memory size. If the maximum heap size is the same as the minimum heap memory size, the memory will not be released to the operating system.

Its important features are ZGC optimization, releasing memory back to the operating system, and introducing NIO to the underlying socket implementation.

New Features of JDK14 (March 2020)

  • Instanceof pattern matching and instanceof type matching syntax simplification can directly assign values to objects, such as if(obj instanceof String str). If obj is a string type, directly assign values to str variables.
  • Introduce the record type, which is similar to the @Data annotation of Lombok. It can automatically generate constructors, equals, getters, and other methods like Lombok.
  • Switch Expression-Standardization
  • Improve the NullPointerExceptions prompt information, print the null pointer exception thrown by the specific method, avoid the trouble that it is impossible to judge which function throws the exception when multiple functions in the same line of code are called, and facilitate exception troubleshooting
  • Delete a CMS garbage collector

New Features of JDK15 (September 2020)

  • EdDSA Digital Signature Algorithm
  • Sealed Classes (Preview): The sealed keyword is used to modify abstract classes to only restrict specified subclasses to implement or inherit abstract classes to avoid abuse of abstract classes.
  • Hidden Classes
  • Remove the Nashorn JavaScript engine
  • Improve java.net.DatagramSocket and java.net.MulticastSocket underlying implementation.

New Features of JDK16 (March 2021)

  • Allows use of C ++ 14 features in the JDK C ++ source code
  • ZGC performance optimization removes the ZGC thread stack processing from the safe point to the concurrent phase.
  • Add Unix Domain Socket Channel
  • Elastic Meta-space Capability
  • Provide the jpackage tool for packaging standalone Java applications

JDK16 is equivalent to the formal introduction of some features of JDK14 and JDK15, such as instanceof pattern matching, record introduction, etc. JDK16 became the final version.

New Features of JDK17 (September 2021) (LTS version)

  • Free Java License
  • JDK 17 will replace JDK 11 as the next long-term support release.
  • Spring 6 and Spring Boot 3 require JDK17.
  • Remove experimental AOT and JIT compilers
  • Restore always-strict floating-point definitions
  • The sealed class is formally introduced to restrict the implementation of abstract classes.
  • Unify log asynchronous refresh. Logs are written to the cache and then asynchronously refreshed.

Although JDK17 is an LTS version, it does not introduce prominent features (like JDK8 and JDK11), mainly integrating and improving the previous versions.

“Frozen” list of JDK 21 functionalities- Sep 23

Stable Features

431: Sequenced Collections

In the case of ordered collections, a consistent interface has been introduced for retrieving the first and last elements, as well as reversing the sequence.

interface SequencedCollection<E> extends Collection<E> {
// new method
SequencedCollection<E> reversed();
// methods promoted from Deque
void addFirst(E);
void addLast(E);
E getFirst();
E getLast();
E removeFirst();
E removeLast();
}

439: Generational ZGC

As the likelihood of a GC needing to “clean up” a given object is reduced with its lifetime, having a different pipeline for short-lived and long-lived objects is standard in GCs and is now introduced to the ZGC.

440: Record Patterns

The ability to easily destructure the Records, allowing specific fields to be extracted from them, and to be used in pattern matching (next JEP).

if (obj instanceof Point(int x, int y)) {
System.out.println(x+y);
}

441: Pattern Matching for switch

Ability to use switch for pattern matching, including advanced options.

static String formatterPatternSwitch(Object obj) {
return switch (obj) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> obj.toString();
};
}

444: Virtual Threads

Introducing into the JVM the concept of threads managed not by the operating system, but by the virtual machine itself.

Thread.builder().virtual().factory();

449: Deprecate the Windows 32-bit x86 Port for Removal

Goodnight, Sweet Prince

451: Prepare to Disallow the Dynamic Loading of Agents

In order to make Java more secure, the developers plan to prohibit the loading of certain categories of Virtual Machine Agents in the future without a special flag.

452: Key Encapsulation Mechanism API

Introducing a standard API into Java that allows the use of a technique known as KEM, used in quantum cryptography algorithms, among others.

Preview Features

430: String Templates (Preview)

The ability to create templated blocks of text in Java, giving much more power and security than string interpolation.

JSONObject doc = JSON_VALIDATE."""
{
"name": \{name},
"phone": \{phone},
"address": \{address}
};
""";

445: Unnamed Classes and Instance Main Methods (Preview)

A change to the Launch Protocol in Java, allowing heavily simplified Java classes to be written, mainly for educational purposes.

void main() {
System.out.println("Hello, World!");
}

442: Foreign Function & Memory API (Third Preview)

Introducing typed interoperability with applications written in C (and in future other compiled languages), as well as native operating system memory.

443: Unnamed Patterns and Variables (Preview)

Introduction to Java _ wildcard, used when we do not want to define a specific expected value/type in pattern matching, and also as a hint to linterers when we know that a declared variable is unnecessary.

if(r instanceof Point(_, int y))

453: Structured Concurrency (Preview)

A set of structures to manage threads (and not only virtual ones) — especially useful for error and cancelation handling.

try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Supplier<String> user = scope.fork(() -> findUser());
Supplier<Integer> order = scope.fork(() ->fetchOrder());
        scope.join().throwIfFailed();
        return new Response(user.get(), order.get());
}

446: Scoped Values (Preview)

An alternative to ThreadLocal, designed primarily with virtual threads in mind.

final static ScopedValue<...> V = ScopedValue.newInstance();
ScopedValue.where(V, <value>).run(() -> {  V.get() });

Incubation

448: Vector API (Sixth Incubator)

The API enabling vector operations, made available by modern processors, waiting for Valhalla Project.

Detailed Explanation of the Terms used above -

https://medium.com/@lalitchaturvedi323/java-present-past-future-detailed-explanation-e7649d06043f

Summary and Outlook

Summary

  1. Spring takes the lead and rushes directly to JDK17. If Spring6 still supports Java8, many technical frameworks should be compatible with Java8. Therefore, Spring should take the lead and develop Java17 together. However, some frameworks do not support JDK17 yet.
  2. Performance Upgrade: After changing from Java8 to Java11 alone, the performance improved by 10% (rewriting the NIO bottom layer), not to mention the JVM-related optimisation to the JDK17 process. However, performance optimization alone is not enough to attract enterprises to upgrade JDK. After all, performance optimization can be achieved by adding machines. Don’t bother upgrading; not to mention there may be a security risk.
  3. JDK21 could become a true classic. Currently, there is no Project loom function, which means there is no coroutine, and the performance is far worse. For example, Alibaba’s open-source JDK8 and JDK11 have a non-intrusive coroutine.

Judging from the development trend, the project loom function has been previewed in JDK19. It can be found that many Java tools in this version have begun to upgrade for loom. Project loom will be officially launched in JDK21, which is a long-term supported version. Please look forward to it.

Various servlet containers, as well as jetty, netty, vert.x, etc., found the corresponding upgrade label in their latest version of the release note, saying they have added certain support. The most important is loom (or virtual thread support). We predict that once JDK21 is released, more software will be developed!

Outlook

The upgrade of JDK is an inevitable trend.

Some people may think the upgrade will cause extra work. Considering security risks, they are less likely to upgrade. There are no substantial benefits but risks. However, considering Oracle will no longer maintain JDK8 and Spring will no longer maintain past versions in the future, to keep up with the times and use the latest technology, this will promote the upgrade of JDK.

When more companies use JDK17, more new frameworks in the future will support JDK17 (at minimum) because it is not worth it to only be compatible with the old JDK. When most frameworks, communities, and forums are discussing JDK17 technologies and various problem-solving methods, enterprises will inevitably be pushed to upgrade.

References

https://zhuanlan.zhihu.com/p/480293185

https://blog.oxings.com/article/31.html

https://blog.csdn.net/best_luxi/article/details/122543074

https://www.alibabacloud.com

--

--