What is new in Java 11 ?

June 28, 2018

Introduction

Java 11 enters to Ramp Down Phase One (RDP1) phase today (28/06/2018). Thus, the main changes, JEPs, it will be released with are set and no new JEP will be added. Check JEP 3: JDK Release Process for more information about RDP and the release process.

This post is basically a very short summary of each JEP as documented in the OpenJDK website and a few examples.

I have tested some of the changes below using the tip (bfd3c5dfcbea) of mainline repo http://hg.openjdk.java.net/jdk/jdk.

All JEPs to be released with Java 11, and covered in this post, is listed here: http://openjdk.java.net/projects/jdk/11/.

JEP 181: Nest-Based Access Control

Very simply, this JEP solves the following problem.

import java.lang.reflect.Field;

public class JEP181 {

  public static class Nest1 {

    private int varNest1;

    public void f() throws Exception {

      final Nest2 nest2 = new Nest2();

      // this is ok
      nest2.varNest2 = 2;

      // this is not ok
      final Field f2 = Nest2.class.getDeclaredField("varNest2");
      f2.setInt(nest2, 2);

    }

  }

  public static class Nest2 {
    private int varNest2;
  }

  public static void main(String[] args) throws Exception {

    new Nest1().f();

  }

}

Above, JEP181 is called the top level type, and together with Nest1 and Nest2, they are nestmates. Because they are nestmates, Nest1 can access the private field varNest2 of nested class Nest2 (line 14). However, if you use reflection as in lines 17–18, it raises an IllegalAccessException. JEP181 solves this problem, thus using reflection here is not going to raise an exception and will work as excepted.

JEP 309: Dynamic Class-File Constants

A new constant pool entry CONSTANT_Dynamic will be added to the class files where the creation of such an entry will be delegated to bootstrap method like invokedynamic call site delegates at runtime.

JEP 315: Improve Aarch64 Intrinsics

As the name indicates, intrinsics, such as for Math.cos and sin, used for (ARM) AArch64 architecture are improved.

JEP 318: Epsilon: A No-Op Garbage Collector

Epsilon is a do nothing Garbage Collector, meaning it is actually not a garbage collector, it will not collect any garbage (memory allocation). It can be used for various reasons as listed in the JEP description, such as performance testing or extremely short lived jobs.

JEP 320: Remove the Java EE and CORBA Modules

Already deprecated in Java 9, Java EE and CORBA Modules are removed. This means:

  • Following packages are removed: java.xml.ws, java.xml.bind, java.activation, java.xml.ws.annotation, java.corba, java.transaction, java.se.ee, jdk.xml.ws, jdk.xml.bind
  • Following tools are removed: wsgen, wsimport, schemagen, xjc, idlj, orbd, servertool, tnames
  • The JNDI CosNamingProvider is removed.
  • Java RMI Compiler (rmic) will no longer produce IDL or IIOP stubs, thus -iiop and -idl flags will be removed.

JEP 321: HTTP Client (Standard)

The incubated HTTP Client API in Java 9 and 10 is standardized under the module java.net.http. This API supports both HTTP 1.1 and 2 and WebSocket through main types HttpClient, HttpRequest, HttpResponse and WebSocket and both sync and async operations.

Here is an example:

import java.net.http.HttpClient;
import java.net.http.HttpClient.Version;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.net.URI;

public class JEP321 {

	public static void main(String[] args) throws Exception {

		final HttpClient hc = HttpClient.newBuilder()
			.version(Version.HTTP_2)
			.build();

		final HttpRequest req = HttpRequest.newBuilder()
			.uri(URI.create("https://metebalci.com"))
			.build();

		final HttpResponse<String> resSync = hc.send(req, BodyHandlers.ofString());

		System.out.println(resSync.statusCode());

		hc.sendAsync(req, BodyHandlers.ofString())
			.thenApply(HttpResponse::statusCode)
			.thenAccept(System.out::println)
			.get();

	}

}

JEP 323: Local-Variable Syntax for Lambda Parameters

Java 10 introduces var for local variables. However, it was not possible to use it in lambda expressions, JEP 323 resolves this problem. So the following code, with (var a) -> a < 5, now runs on Java 11.

import java.util.Arrays;

public class JEP323 {

  public static void main(String[] args) {

    var xs = new int[]{3, 2, 6, 4, 8, 9};

    int x = Arrays.stream(xs).filter((var a) -> a < 5).sum();

    System.out.println(x);

  }

}

JEP 324: Key Agreement with Curve25519 and Curve448

RFC 7748, the key agreement using Curve25519 and Curve448 is implemented in SunEC provider.

JEP 327: Unicode 10

Java 11 will support Unicode 10. Since Java 10 supports Unicode 8, that means both Unicode 9 and Unicode 10 changes will be implemented. However, Unicode Collation Algorithm, Unicode Security Mechanisms, Unicode IDNA Compatibility Processing, and Unicode Emoji will not be implemented.

JEP 328: Flight Recorder

Flight Recorder is a low overhead (under 1% performance impact) data / event collection framework. Applications, JVM or OS can produce data as events, and these will be buffered and serialized to a binary format, and then can be consumed for various means, such as troubleshooting.

This deserves a post on its own, but a simple demonstration is here. This example writes an event every second if run with an argument, otherwise, it reads the 1.out event output and dumps its contents.

import jdk.jfr.*;
import jdk.jfr.consumer.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class JEP328 extends Event {

  @Label("message")
  String message;

  public static void main(String[] args) throws Exception {

    if (args.length > 0) {

      for (int i = 0; i < 100; i++) {

        final JEP328 j = new JEP328();
        j.message = String.valueOf(i);
        j.commit();

        Thread.sleep(1000);

      }

    } else {

      Path p = Paths.get("1.out");
      for (RecordedEvent e : RecordingFile.readAllEvents(p)) {
        final List<ValueDescriptor> lvd = e.getFields();
        System.out.println(e.getStartTime());
        for (ValueDescriptor vd : lvd) {
          System.out.println(vd.getLabel() + "=" + e.getValue(vd.getName()));
        }
        System.out.println("***");
      }

    }

  }
}

We can run it with flight recorder using -XX:StartFlightRecording option.

$ java -XX:StartFlightRecording JEP328 x
Started recording 1. No limit specified, using maxsize=250MB as default.

Use jcmd 27866 JFR.dump name=1 filename=FILEPATH to copy recording data to file.

Then, at any time, we can dump the events.

$ jcmd 27866 JFR.dump name=1 filename=1.out
27866:
Dumped recording "1", 236.6 kB written to:

/home/mete/Dropbox/metebalci.com/includes/1.out

If we dumpt the contents of events:

$ java JEP328

There are many, but this is one of the events we wrote:

2018-12-05T11:34:24.774255597Z
Start Time=1090584204
Duration=0
Event Thread={
  osName = "main"
  osThreadId = 27867
  javaName = "main"
  javaThreadId = 1
  group = {
    parent = {
      parent = null
      name = "system"
    }
    name = "main"
  }
}

Stack Trace={
  truncated = false
  frames = [
    {
      method = {
        type = {
          classLoader = {
            type = {
              classLoader = {
                type = null
                name = "bootstrap"
              }
              name = "jdk/internal/loader/ClassLoaders$AppClassLoader"
              package = {
                name = "jdk/internal/loader"
                module = {
                  name = "java.base"
                  version = "11.0.1"
                  location = "jrt:/java.base"
                  classLoader = {
                    type = null
                    name = "bootstrap"
                  }
                }
                exported = true
              }
              modifiers = 32
            }
            name = "app"
          }
          name = "JEP328"
          package = null
          modifiers = 33
        }
        name = "main"
        descriptor = "([Ljava/lang/String;)V"
        modifiers = 9
        hidden = false
      }
      lineNumber = 20
      bytecodeIndex = 30
      type = "Interpreted"
    }
  ]
}

message=0

JEP 329: ChaCha20 and Poly1305 Cryptographic Algorithms

ChaCha20 and Poly1305 algorithms specified in RFC 7539 will be implemented in the SunJCE provider.

JEP 330: Launch Single-File Source-Code Programs

It will be possible to run a single-file Java source-code like:

java SourceCode.java

which will be roughly equivalent to:

javac -d <memory> SourceCode.java
java -cp <memory> ClassInSourceCodeJava

This will also make it possible to add #!path-to-java -source 11 to the first line of the file, make it executable and directly run. For this, change the file extension something other than .java.

JEP 331: Low-Overhead Heap Profiling

With the new JVMTI SampledObjectAlloc callback, it will be possible to trace the (individual or sampled) heap allocations and their locations in a low-overhead framework.

JEP 332: Transport Layer Security (TLS) 1.3

TLS 1.3 is now supported, however without 0-RTT data, Post-handshake authentication, and Signed certificate timestamps (SCT) (RFC 6962) support.

JEP 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)

An experimental low-latency garbage collector, Z Garbage Collector, ZGC, is introduced, aiming to have maximum 10ms pause time and have no more than 15% performance impact compare to G1 garbage collector. At the moment, it will be only supported on Linux/x64 platform.

JEP 335: Deprecate the Nashorn JavaScript Engine

Nashorn is now deprecated and will probably be removed in the future.

JEP 336: Deprecate the Pack200 Tools and API

Pack200 compression tools that are used for JAR files is now deprecated and will probably be removed in the future.