What's coming in JDK 14
Ashish Garg
Posted on February 22, 2020
JDK 14 is due to release March 2020, feature supposed to part of this release has been frozen. A list of JEPs identified for inclusion:
JEPs
These JEPs can be divided into two parts from feature perspective:
Finalized
- (JEP 345) NUMA aware memory allocation for G1
- (JEP 349) JFR Event Streaming
- (JEP 352) Non-Volatile mapped with Byte Buffers
- (JEP 358) Helpful NullPointerExceptions
- (JEP 361) Switch Expressions
Preview or Incubating
- (JEP 305) Pattern Matching for instanceof
- (JEP 343) Packaging Tool
- (JEP 359) Records
- (JEP 368) Text Blocks
- (JEP 370) Foreign-Memory Access API
Stuffs that has been removed or deprecated are covered under
- (JEP 362) Deprecate the Solaris and SPARC Ports
- (JEP 363) Remove the Concurrent Mark Sweep (CMS) Garbage Collector
- (JEP 366) Deprecate the ParallelScavenge + SerialOld GC Combination
- (JEP 367) Remove the Pack200 Tools and API
ZGC (Garbage Collector) before JDK 14 was supported on Linux only, it has been extended for
I will be covering JEPs which are finalized first then I be touching preview/Incubator as well.
Switch Expressions (JEP 361)
This was released as preview feature in JDK 12 and JDK 13 and It has been standardized (freezes) with JDK 14 incorporating feedback from developer community. Existing implementation of Switch follows the design and syntax of C and C++ and supports fall through.
Before talking about switch expressions let's first understand shortcoming of existing switch statement:
- Fall through behaviour between switch labels
- Default scoping in switch blocks (the whole block is treated as one scope)
- Quite verbose, not easy to read as more ‘breaks’ add into switch block
This JEP introdcued below changes
A new form of switch label, “case L ->”, to signify that only the code to the right of the label is to be executed if the label is matched
If a label is matched, then only the expression or statement to the right of the arrow is executed; there is no fall through
Switch statement are extended so they can be used as expression
Most switch expression will have a single value to right of ‘case ->’, in case you need block ‘yield’ has been introduced
In case of switch expression a default case is required to emphasize that all possible cases are considered, default case can be skipped if you are using Enum as case identifier, compiler can see if all cases are covered or not
Helpful NullPointerExceptions (JEP 358)
This JEP introduced NPE message to specifically tell which variable is actually caused this exception. Existing log message will tell you filename and line from where NPE has been thrown but it will not tell you that which variable caused this
With this JEP i.e. NPE from assignment obj.temp = 10; could generate:
Exception in thread “main” java.lang.NullPointerException:
Cannot assign field “temp” because “obj” is null
at Test.main(Test.java:6)
Note:- Only NPEs that are created and thrown directly by the JVM will include the null-detail message. NPEs that are explicitly created and/or explicitly thrown by programs running on the JVM are not subject to the bytecode analysis and null-detail message.
In addition, the null-detail message is not reported for NPEs caused by code in hidden methods, which are special-purpose low-level methods generated and called by the JVM to, e.g., optimize string concatenation. A hidden method has no filename or line number that could help to pinpoint the source of an NPE, so printing a null-detail message would be futile.
This feature is not enabled by default, it can be enabled by command-line option -XX:+ShowCodeDetailsInExceptionMessages. It’s not turned on by default because:
- Performance - Algorithm add some overhead to the production of stack trace
- Security - Detail message give information about insight of source code, you might not want this for production applications
- Compatibility - Some tool might got broken because of this new message format
Feature flag might not be required for future JDK releases
Computation of detail NPE message might not work in below scenario
- When executing remote code via RMI
- If the bytecode instructions of a method change while a program is running, such as due to redefinition of the method by a Java agent using JVMTI
Non-Volatile mapped with Byte Buffers (JEP 352)
Primary goal is allows java program to update NVM (Non-volatile Memory) from a java program efficiently and coherently. The target OS/CPU platform combinations for this JEP are Linux/x64 and Linux/AArch64. This restriction is imposed for two reasons. This feature will only work on OSes that support the mmap system call MAP_SYNC flag, which allows synchronous mapping of non-volatile memory. That is true of recent Linux releases. It will also only work on CPUs that support cache line writeback under user space control. x64 and AArch64 both provide instructions meeting this requirement.
Note - Recent Windows/X64 releases do support the mmap MAP_SYNC flag, however it’s not supported by this JEP as of now.
NVM offers the opportunity for application programmers to create and update program state across program runs without incurring the significant copying and/or translation costs that output to and input from a persistent medium normally implies. This is particularly significant for transactional programs, where regular persistence of in-doubt state is required to enable crash recovery.
NUMA aware memory allocation for G1 (JEP 345)
Modern multi-socket machines increasingly have non-uniform memory access (NUMA), that is, memory is not equidistant from every socket or core. Memory accesses between sockets have different performance characteristics, with access to more-distant sockets typically having more latency.
Large enterprise applications in particular tend run with large heap configurations on multiple sockets, yet they want the manageability advantage of running within a single JVM.
G1’s heap is organized as a collection of fixed-size regions. A region is typically a set of physical pages, although when using large pages (via -XX:+UseLargePages) several regions may make up a single physical page.
If the +XX:+UseNUMA option is specified then, when the JVM is initialized, the regions will be evenly spread across the total number of available NUMA nodes.
JFR Event Streaming (JEP 349)
To consume the data today, a user must start a recording, stop it, dump the contents to disk and then parse the recording file. This works well for application profiling, where typically at least a minute of data is being recorded at a time, but not for monitoring purposes. An example of monitoring usage is a dashboard which displays dynamic updates to the data.
Under this JEP, an API has been introduced which can asynchronously publish event to all subscribers which much lower overhead.
Pattern Matching with InstanceOf(JEP 305)
All Java programmers are familiar with the instanceof-and-cast idiom:
private static void instanceOfExist(Object obj){
if(obj instanceof String){
String s =(String)obj;
//use s
}
}
This is bit weird event after testing a instance type you have do explicit casting and assignment which is not optimal, This JEP has been implemented to address it via pattern matching.
After this JEP above code coule be written like this:
private static void newInstanceOf(String str){
if(str instanceof String s){
// can use s here
}else{
// can't use s here
}
}
The instanceof operator “matches” the target obj to the type test pattern as follows: if obj is an instance of String, then it is cast to String and assigned to the binding variable s. The binding variable is in scope of true block and not in the false block of if statement.
Packaging Tool (JEP 343)
To run a java application typically we need JVM to install and running on a machine. This JEP has been target to come up with a packing tool which can generate binary in native format. These formats include msi and exe on Windows, pkg and dmg on macOS, and deb and rpm on Linux.
There is no GUI for this tool, supported as CLI only.
Packaging tool will be platform specific i.e. to generate a binary (exe) for windows you need to run packaging tool on windows only.
Developers can use jlink to strip the JDK down to the minimal set of modules that are needed, and then use the packaging tool to produce a compressed, installable image that can be deployed to target machines.
An application image contains both the files comprising your application as well as the JDK runtime image that will run your application.
- Non-modular Applications
Suppose you have an application composed of JAR files, all in a directory named lib, and that lib/main.jar contains the main class. Then the command
$ jpackage — name myapp — input lib — main-jar main.jar
will package the application in the local system’s default format, leaving the resulting package file in the current directory.
- Modular Applications
If you have a modular application, composed of modular JAR files and/or JMOD files in a lib directory, with the main class in the module myapp, then the command
$ jpackage — name myapp — module-path lib -m myapp
Records (JEP 359)
In an enterprise application we create lots of the classes as data carrier. To write a proper data carrier a developer need to write a lot of code i.e. constructors(), toString(), hashcode(), equals() etc. which is repeatable and error prone even I often notices developers are skipping to wrote these methods which resultant to production issues.
Most of IDEs these days help to generate such code but reader still not able to recognized which class wrote by developer as pure intention of data carrier.
This JEP has been targeted with the intention that It should be easy, clear, and concise to declare shallowly-immutable, well-behaved nominal data aggregates.
Records are a new kind of type declaration in the Java language. Like an enum, a record is a restricted form of class. A record has simply a name and state description. For Example:
record Point(int x, int y) { }
A record get many standard functionality automatically:
- A private final field for each component of the state description
- A public read accessor method for each component of the state description, with the same name and type as the component
- A public constructor, whose signature is the same as the state description, which initializes each field from the corresponding argument
- Implementations of equals and hashCode that say two records are equal if they are of the same type and contain the same state; and
- An implementation of toString that includes the string representation of all the record components, with their names
Note- Any of the members that are automatically derived from the state description can also be declared explicitly. However, carelessly implementing accessors or equals/hashCode risks undermining the semantic invariants of records.
Similar functionality exist in other OO languages based on JVM i.e. data classes in Kotlin and case classes in Scala.
### Restriction of Records
- Cannot extend another class
- Cannot declare instance field other than private final other declared field must be static
- Records are implicitly final, and cannot be abstract
TextBlocks (JEP 368)
It’s initially introduced with JDK 13 as preview feature, it has been re-preview again with JDK 14 with certain modification.
A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over the format when desired.
Have you ever embedded a snippet of HTML, XML, SQL, or JSON in a string, do you like all escape and new line sequences need to be added?
Here how we write today:
String html = “<html>\n” +
“ <body>\n” +
“ <p>Hello, world</p>\n” +
“ </body>\n” +
“</html>\n”;
After this JEP, we can write same as
String html = “””
<html>
<body>
<p>Hello, world</p>
</body>
</html>
“””;
Text blocks do not directly support string interpolation. Interpolation may be considered in a future JEP.
Foreign Memory Access API (JEP 370)
Introduce an API, to safely access and efficiently access memory outside Java heap. Many existing java library access foreign memory; those are in business of cache i.e. memcached.
Introduces three main abstractions:
- MemorySegment is used to model a contiguous memory region with given spatial and temporal bounds
- MemoryAddress can be thought of as an offset within a segment
- MemoryLayout is programmatic description of a memory segment’s contents
Deprecate the Solaris and SPARC Ports (JEP 362)
Deprecate the Solaris/SPARC, Solaris/x64, and Linux/SPARC ports, with the intent to remove them in a future release
Remove the Concurrent Mark Sweep (CMS) Garbage Collector (JEP 363)
More than 2 years CMS was marked deprecated, it has been removed from JDK14 with this JEP. G1 is default garbage collector with JDK 14.
Deprecate the ParallelScavenge + SerialOld GC Combination (JEP 366)
There is one combination of GC algorithms that is rarely used in production application but requires a significant amount of maintenance effort: The pairing of the parallel young generation GC (called ParallelScavenge) and the serial old GC (called SerialOld).
As this combination has been deprecated, trying to use it will display a warning.
In future depends upon community it might be un-deprecated or removed from JDK.
Remove the Pack200 Tools and API (JEP 367)
This JEP is for removing pack200 and unpack200 tools along with pack200 API. These had been marked deprecated with JDK 11.
Posted on February 22, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 21, 2024