25 March 2022

4+1 important features coming with Java 18 SE/JDK

Time is running forward without any compromises and the six month JDKrelease period is over. Similar to people expecting spring and nice weather, the Java community is excited about the next SE and JDK release that holds number 18. Yes, Java 18 is here and in this article we explore the most important changes together with features added since the preview.

Before we start introducing a particular feature, let’s share some thoughts about the kind and focus of those changes. We are aware that computers understand binary pretty well, but what about humans? For humans, number sequences are important but for us more informative values contain Strings. Strings concepts are very helpful to communicate information from the program to the user, not only ;)

The breakthrough feature: default encoding

Well now, the String concept is a focus point in the new Java JDK 18 release. In my opinion the platform has been struggling for a very long time by lacking default encoding (Example 1.). The 18 release cures this struggle by bringing the default UTF-8 encoding. It may not be so obvious, but encoding impacts the platform on many different levels, from properly displayed values to the client, to the correct internet address resolution and Java string pool or garbage collection.

It means release 18 is making the Java platform much more stable and predictable than ever before!

java.io.FileReader(hello.txt) -> こんにちは (macOS)
java.io.FileReader(hello.txt) -> ã?ã‚“ã?«ã?¡ã?  (Windows (en-US))
java.io.FileReader(hello.txt) -> 縺ォ縺縺ッ (Windows (ja-JP)

Example 1.:: java.io.FileReader and encoding issue due to the system platform encoding highlighted on a Japanese file. File content is in UTF-8.

Let’s now dive deeper into some other interesting accepted features:

1. JEP-400: UTF-8 by Default

component: core-libs/java.nio.charsets

From JDK 18 onwards, UTF-8 encoding is taken as the default encoding for Java SE API’s. It means that every API that depends on the default encoding variable will be set to UTF-8. It contributes to the more consistent and predictable program behavior.

details: JEP-400, JDK-8187041

2. JEP-418: Internet-Address Resolution SPI

component: core-libs/java.net

The goal is to define a service-provider-interface (SPI) for the host name and address resolution as the API currently uses the operating system’s native resolver, which is typically configured to use a combination of a local “hosts” file and the Domain Name System (DNS). The package “java.net.spi” contains a set of new classes (InetAddressResolverProvider, InetAddressResolver etc.)

details: JEP-418

3. JEP-192: String deduplication in G1

component: hotspot/gc

The goal is to reduce a Java heap live-data set by enhancing the G1 garbage collector so that duplicate instances of String are automatically and continuously deduplicated. The impact of the JEP is bit broader, which has a positive impact on overall stability:

details: JEP-192

4. JEP-413: Code Snippets in Java API Documentation

module: tools/javadoc(tool)

The JEP introduces a new annotation @snippet. The goal of this annotation is to reduce a duplication in writing documentation in JavaDoc’s standard Doclet. It is pretty handy as the tag allows a direct reference to the already written code and it’s not required to duplicate it which has a positive effect on maintainability.


Img 1.:: Sample project structure

/**
 * function represent important production logic
 * {@code ProductionCode.function}:{@snippet file="com/ProductionCodeTest.java" region="function"}
 * 
 * @param active production activation
 * @return production status
 */
 public boolean function(boolean active){
    System.out.println("this is very important production function");
    return !active;
}

Example 2.:: Documented method with link to the external resource from Img 1.

/**
 * simple tests
 *
 * @param args arguments
 */
 // @start region=function
 public static void main(String[] args) {
    var production = new ProductionCode();
    var active = production.function(true);
    System.out.println("""
        test status=%s""".formatted(active));
    assert active == true: "should be true ";
}
// @end region=function

Example 3.:: Reference method with the highlighted code part in the file ProductionCodeTest, see Example 1.

The documentation based on the provided structure could be generated by the following command (Example 4.). The structure is according to the structure above.

$ javadoc -d doc -sourcepath src -subpackages com --snippet-path  test

Example 4.:: JavaDocs generation


Img 2.:: Java doc result with usage of @snippet annotation

detials: JEP-413, JDK-8201533

5. JEP 408: Simple Web Server

component: core-libs/java.net

Providing a simple command-line tool to start a minimal web-server with static content. This util comes in very handy for many cases, like prototyping, ad-hoc coding or testing and more. For more background see the module jdk.httpserver and its package com.sun.net.httpserver.


Img 3.:: Simple http server in action

$ jwebserver 
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving <EXAMPLE_DIRECTORY> and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/
127.0.0.1 - - [24/Mar/2022:16:34:17 +0100] "GET / HTTP/1.1" 200 -

Example 5.:: Command to run the jdk18 http server

details: JEP-408, JDK-8260510

Aside of accepted JEPs java 18 introduces other enhancements that is worthwhile to mention:

  • Passing Originating Elements From Filer to JavaFileManager JDK-8272234
  • Improve Compilation Replay JDK-8254106
  • Allow G1 Heap Regions up to 512MB JDK-8275056
  • JDK Flight Recorder Event for Finalization JDK-8266936
  • New System Property to Control the Default Date Comment Written Out by java.util.Properties::store Methods
  • ObjectInputStream.GetField.get(name, object) Throws ClassNotFoundException JDK-8276665
  • others

A new release is not always coming with new features. It always comes hand in hand with some clean up and removals. Let’s discuss some deprecations that are notable

JEP 421: Deprecate Finalization for Removal

component: core-libs / java.lang

Deprecated Finalization for Removal JDK-8274609. It basically recommends developers to use construction try-with-resources or cleaner as preferred alternatives to the finalize() method. This JEP also helps developers to understand its issues and prepare for the complete removal in one of the next releases.

details : JEP-421

With having Finalization deprecated Java 18 comes with the removal of empty finalize methods, see removal of empty finalize() methods in java.desktop Module JDK-8273102. The release also deprecated, finally, the Thread.stop method JDK-8277861, which has been deprecated since Java 1.2 (1998) due to the unsafe behavior

Preview features

JEP-420: Pattern Matching for switch (Second Preview) (JDK-8273326)

component: specification/language

The feature may be quite expected by the community. It allows creating very handy switch statements and minimizing side effects, like a “break”, and allowing a direct return. Such semantic improvements together with the default UTF-8 encoding is making this preview feature a hot candidate. Hopefully we see it fully implemented in the next release.

String formatted = switch (o) {
    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);
    Case null 	   -> String.format("NULL value");
    default        -> o.toString();
};

Example 6.:: Type pattern matching may include type, enum, record or array type, null is considered too

details: JEP-420

JEP 417: Vector API (Third Incubator)

component: core-libs

The goal of this JEP is to deliver a platform agnostic implementation of the optimal instruction vector runtime calculation. The implementation should be reliable.

details: JEP-417, JDK-8269306

JEP 419: Foreign Function & Memory API (Second Incubator)

component: core-libs

The JEP proposes a transparent and easy to use API to interoperate with code or data outside of the Java runtime. The JEP promises to effectively invoke a foreign function and also a safe access to the foreign memor. It promises that the program is allowed to call native libraries without usage or obstacles created by JNI. One of the goals is to replace the Java Native Interface with a Java based development model.

details: JEP-419, JDK-8274073

Conclusion

Java 18 SE/JDK release is another six months iteration and it is coming with stability that would have been nice to have in LTS release 17, namely default string encoding. The article has shown the broad impact of such change on overall platform stability. It means it will be easier to observe similar behavior across the system platforms without facing unexpected encoding challenges. The article also showed new possibilities of generating JavaDocs, where encoding also plays an important role (Example 2.-4., Img 1.-2.). We have also touched on upcoming semantic changes ( and ability to communicate with external JVMs without using any JNI functionalities.

References

  1. JDK-18 release notes

Miro Wengner

Miro is a member of the JCP program for very long time. He contributes to the OpenJDK, Mission Control project. His focus is on java performance and maintainability. Miro's involvement can be seen in various another open-source projects such as OpenTracing, Pi4J and etc. He is also co-author of Robo4j project which has been awarded by DukeChoice Award 2017. Miro has been recognized as JavaChampion, Oracle ACEPro, RockStar speaker. Aside of his daily duties as a Principal Engineer at OpenValue he shares his knowledge over conferences (JavaOne, CodeOne, Devoxx, GeeCON etc.) and blogging.