What's New in Java 9

61
What’s New in Java 9 Richard Langlois P. Eng. Solutions Architect May 3rd, 2017

Transcript of What's New in Java 9

What’s New in Java 9

Richard Langlois P. Eng. Solutions Architect

May 3rd, 2017

Key Changes in JDK 9

What’s New for Tools JDK 9

What’s New for Security in JDK 9

What’s New for Deployment in JDK 9

What’s New for the Java Language in JDK 9

What’s New for Javadoc in JDK 9

What’s New for the VM in JDK 9

What’s New in Core Libraries in JDK 9

What’s New for Internationalization in JDK 9

Q & A

Agenda

2

Will reach General Availability on July 27, 2017.

Availability

3

Key Changes in JDK 9

4

Changes includes:

Tools javac, jlink and java accept options to specify module paths (-mp)

Module:

Unit of software that declares the answers to three questions about itself in a file named module‐info.java:

What is its name?

What does it export?

What does it require?

JEP 261: Module System (1 of 2)

5

Where

Module Name should be following something similar to the package convention

e.g. com.alithya.mymodule, to avoid conflicts.

By convention, modules are placed in a folder that shares the same name as the module

Exports section lists all the packages of this particular module that are considered public API and thus usable by other modules.

Note: If a class is not in an exported package, no one outside of your module can access it – even if it is public

Requires section lists all modules that this module depends on – all public types that those modules export are accessible by the module in question.

Note: The Jigsaw team is trying to establish the phrase “reading another module”.

JEP 261: Module System (2 of 2)

6

Module de.codecentric.addresschecker uses module de.codecentric.zipvalidator to validate zip code.

zipvalidator is specified by the following module‐info.java:

module de.codecentric.zipvalidator{

exports de.codecentric.zipvalidator.api;

}

Exports the de.codecentric.zipvalidator.api package and does not read any other module (except for java.base).

Addresschecker is specified by the following module‐info.java:

module de.codecentric.addresschecker{

exports de.codecentric.addresschecker.api;

requires de.codecentric.zipvalidator;

}

Reads de.codecentric.zipvalidator module

JEP 261: Module System – Example (1 of 12)

7

Overall file system structure:

two‐modules‐ok/

├── de.codecentric.addresschecker

│ ├── de

│ │ └── codecentric

│ │ └── addresschecker

│ │ ├── api

│ │ │ ├── AddressChecker.java

│ │ │ └── Run.java

│ │ └── internal

│ │ └── AddressCheckerImpl.java

│ └── module‐info.java

├── de.codecentric.zipvalidator

│ ├── de

│ │ └── codecentric

│ │ └── zipvalidator

│ │ ├── api

│ │ │ ├── ZipCodeValidator.java

│ │ │ └── ZipCodeValidatorFactory.java

│ │ ├── internal

│ │ │ └── ZipCodeValidatorImpl.java

│ │ └── model

│ └── module‐info.java

JEP 261: Module System – Example (2 of 12)

8

Example with a well-behaved code:

public class AddressCheckerImpl implements AddressChecker {

@Override

public boolean checkZipCode(String zipCode) {

return ZipCodeValidatorFactory.getInstance().zipCodeIsValid(zipCode);

}

}

Compile zipvalidator module:

javac ‐d de.codecentric.zipvalidator $(find de.codecentric.zipvalidator ‐name "*.java")

No need to use modules (-mp) since zipvalidator does not depend on any custom module.

Compile addresschecker module:

javac ‐modulepath . ‐d de.codecentric.addresschecker $(find de.codecentric.addresschecker ‐name "*.java")

Modulepath tells javac where to find the compiled modules (in this case, this is .)

Compiling multiple modules at once using ‐modulesourcepath:

javac ‐d . ‐modulesourcepath . $(find . ‐name "*.java")

JEP 261: Module System – Example (3 of 12)

9

Run the example:java ‐mp . ‐m de.codecentric.addresschecker/de.codecentric.addresschecker.api.Run 76185

Output:

76185 is a valid zip code

Note:

Specify a modulepath so that the JVM knows where to find the compiled modules

Specify a main class (Run) and a parameter (76185)

JEP 261: Module System – Example (4 of 12)

10

Modular Jar

very similar to a regular jar, but it also contains a compiled module‐info.class.

Example:

Build a jar for the zipvalidator:jar ‐‐create ‐‐file bin/zipvalidator.jar ‐‐module‐version=1.0 ‐C de.codecentric.zipvalidator .

Note:

specify an output file

a version

module to package.

Build a jar for the addresschecker:jar ‐‐create ‐‐file=bin/addresschecker.jar ‐‐module‐version=1.0 ‐‐main‐class=de.codecentric.addresschecker.api.Run \

‐C de.codecentric.addresschecker .

Running:

java ‐mp bin ‐m de.codecentric.addresschecker 76185

Note: No need to specify a main class as the Manifest of addresschecker.jar already contains this information.

JEP 261: Module System – Example (5 of 12)

11

Running:

java ‐mp bin ‐m de.codecentric.addresschecker 76185

Note:

Specify the modulepath which in this example is the bin folder which we wrote our jars to

No need to specify a main class as the Manifest of addresschecker.jar already contains this information.

JEP 261: Module System – Example (6 of 12)

12

Jigsaw does not only include compile-time checks, but also runtime checks

Example: Directly using non-exported types:

public class AddressCheckerImpl implements AddressChecker {

@Override

public boolean checkZipCode(String zipCode) {

return new de.codecentric.zipvalidator.internal.ZipCodeValidatorImpl().zipCodeIsValid(zipCode);

}

}

When compiled:

error: ZipCodeValidatorImpl is not visible because

package de.codecentric.zipvalidator.internal is not visible

Note: fails at compile time.

Using reflection will compile but throw IllegalAccessException at runtime:

java.lang.IllegalAccessException: class de.codecentric.addresschecker.internal.AddressCheckerImpl

(in module de.codecentric.addresschecker) cannot access class [..].internal.ZipCodeValidatorImpl

(in module de.codecentric.zipvalidator) because module de.codecentric.zipvalidator does not export package de.codecentric.zipvalidator.internalto module de.codecentric.addresschecker

JEP 261: Module System – Example (7 of 12)

13

Circular dependencies

In the next case, we have suddenly realized that the addresschecker module contains a class in its API that the zipvalidator would very much like to use. Since we’re lazy, instead of refactoring the class to another module, we declare a dependency to the addresschecker:

module de.codecentric.zipvalidator{

requires de.codecentric.addresschecker;

exports de.codecentric.zipvalidator.api;

}

When compiling:

./de.codecentric.zipvalidator/module‐info.java:2:

error: cyclic dependence involving de.codecentric.addresschecker

JEP 261: Module System – Example (8 of 12)

14

Implied readability

Adding the keyword public to the requires definition, we tell all client modules that they also need to read another module.

e.g.

requires public de.codecentric.zipvalidator.model;

Lets zipvalidator use another module: de.codecentric.zipvalidator.model.

module de.codecentric.zipvalidator{

exports de.codecentric.zipvalidator.api;

requires de.codecentric.zipvalidator.model;

}

JEP 261: Module System – Example (9 of 12)

15

New file structure:

three‐modules‐ok/

├── de.codecentric.addresschecker

│ │ │ ├── …

├── de.codecentric.zipvalidator

│ │ │ └── …

├── de.codecentric.zipvalidator.model

│ ├── de

│ │ └── codecentric

│ │ └── zipvalidator

│ │ └── model

│ │ └── api

│ │ └── ZipCodeValidationResult.java

│ └── module‐info.java

JEP 261: Module System – Example (10 of 12)

16

New file structure:

@Override

public <strong>ZipCodeValidationResult</strong> zipCodeIsValid(String zipCode) {

if (zipCode == null) {

return ZipCodeValidationResult.ZIP_CODE_NULL;

[snip]

} else {

return ZipCodeValidationResult.OK;

}

}

The addresschecker module has been adapted to work with this enum as return type as well,

When compiling:

./de.codecentric.addresschecker/de/[..]/internal/AddressCheckerImpl.java:5:

error: ZipCodeValidationResult is not visible because package

de.codecentric.zipvalidator.model.api is not visible

JEP 261: Module System – Example (11 of 12)

17

Note:

the zipvalidator uses exported types from the zipvalidator model in its public API.

Since the addresschecker does not read this module, it cannot access this type.

Solution:

module de.codecentric.zipvalidator{

exports de.codecentric.zipvalidator.api;

requires public de.codecentric.zipvalidator.model;

}

Note:

The public keyword tells all modules that read the zipvalidator that they also need to read the zipvalidator model.

JEP 261: Module System – Example (12 of 12)

18

Modularizes the Java Platform Module System (JPMS)

The modules can be combined:

Configurations corresponding to the JRE and JDK

Configuration equivalent in content to each of the Compact Profiles defined in JDK 8

e.g. compact1, compact2

Custom configurations that contain only a specified set of modules and their required modules.

JEP 200: The Modular JDK (1 of 3)

19

JEP 200: The Modular JDK (2 of 3)

20

JDK 9 vs JDK 8

You can now specify which modules of the Java Runtime you want to use

At the bottom of the graph resides java.base.

Every module you create reads java.base

java.base exports packages such as java.lang, java.util, java.math, etc.

JEP 200: The Modular JDK (3 of 3)

21

Restructures the JDK and JRE runtime images to accommodate modules.

Removes the rt.jar and tools.jar from JRE:

Class and resource files previously stored in lib/rt.jar, lib/tools.jar, lib/dt.jar and various other internal jar files are stored in a more efficient format in implementation-specific files in the lib directory.

Removes the endorsed-standards override mechanism:

The java.endorsed.dirs system property and the lib/endorsed directory are no longer present

Remember the old days with XML parser like Xerces

Use upgradeable modules mechanism instead

JEP 220: Modular Runtime Images

22

Makes most of the JDK’s internal APIs inaccessible by default

But widely used internal APIs (e.g. sun.misc.Unsafe) still accessible by requiring the jdk.unsupported module.

Module declaration for jdk.unsupported:

jdk.unsupported {

exports sun.misc;

exports sun.reflect;

exports com.sun.nio.file;

opens sun.misc;

opens sun.reflect;

}

To use Unsafe:

module alithyaModule {

requires jdk.unsupported;

}

To determine whether your code uses internal JDK APIs:

jdeps –jdkinternals

JEP 260: Encapsulate Most Internal APIs

23

Simplified version-string format.

New format:

$MAJOR.$MINOR.$SECURITY.$PATCH+$BUILD

e.g. 9.0.5+20

Where:

$MAJOR: version number for a major release (e.g. 9 for JDK 9)

$MINOR: version number for a minor update (e.g. bug fixes)

$SECURITY: version number for a security-update release

$PATCH: version number for a release containing security and high-priority customer fixes.

$BUILD: version of the build

New java.lang.Runtime.Version class parses, validates, and compares version strings.

JEP 223: New Version-String Scheme

24

Considering Java 9u5 release:

Before JDK 9, the version string would be:

1.9.0_5-b20.

Using JDK 9:

the Short version: 9.0.5,

the Long version: 9.0.5+20

Using JDK9’s Version class:

Version version = Runtime.version(); // version contains list: 9,0,5,20

String major = version.major(); // major contains 9

String minor = version.minor(); // minor contains 0

String security = version.security(); // security contains 5

String build= version.build(); // major contains 20

JEP 223: New Version-String Scheme - Example

25

What’s New for Tools in JDK 9

26

Adds Read-Eval-Print Loop (REPL) functionality to the Java Platform. You type Java code, and it immediately evaluates it.

The Jshell tool continually reads user input, evaluates the input, and prints the value of the input or a description of the state change the input caused.

Some of you may recognize Venkat Subramaniam’s special REPL based editor:

Jshell API enables applications (e.g. Eclipse) to leverage REPL functionality.

JEP 223: The Java Shell (REPL)

27

Assembles and optimizes a set of modules and their dependencies into a custom runtime image.

JEP 282: jlink: The Java Linker

28

What’s New for Security in JDK 9

29

JEP 219 Datagram Transport Layer Security (DTLS)

JEP 244: TLS Application-Layer Protocol Negotiation Extension

JEP 249: OCSP Stapling for TLS

JEP 246: Leverage CPU Instructions for GHASH and RSA

JEP 273: DRBG-Based SecureRandom Implementation

JEP 229: Create PKCS12 Keystores by Default

JEP 287: SHA-3 Hash Algorithms

SHA3-224, SHA3-256, SHA3-384, SHA3-512

What’s New for Security

30

What’s New for Deployment in JDK 9

31

Deprecate the Java Plug-in

Enhanced Java Control Panel

rewritten as a JavaFX application

location of some functions has changed

JEP 275: Modular Java Application Packaging

JDK modules enabling the Java Packager to reduce the size of the bundled runtime image

JEP 289: Deprecate the Applet API

The Applet class will be considered for removal in future release

What’s New for Deployment

32

What’s New for the Java Language in JDK 9

33

Project Coin introduced a set of small language changes to JDK 7.

JDK 9 improves on these changes:

Allow @SafeVargs on private instance methods

Allow effectively-final variables to be used as resources in the try-with-resources statement

Pre-Java 9: try (FileInputStream fis2 = fis) [requires fresh variable]

Java 9: try (FileInputStream fis)

Allow diamond with anonymous classes if the argument type of the inferred type is denotable

Complete the removal, begun in Java SE 8, of underscore from the set of legal identifier names

Java 10 will rehabilitate underscore to indicate unused lambda parameter

Support for private methods in interfaces

Will allow common code to be extracted to methods that will remain encapsulated within the interface

JEP-213: Milling Project Coin

34

4 new methods in the Stream interface:

takeWhile(Predicate):

it continue to take elements from the input stream and pass them to the output stream until the test method of the Predicate returns true

dropWhile(Predicate):

It drops elements on the input stream until the test method of the Predicate returns true. All remaining elements in the input stream will then be passed to the output stream.

ofNullable(T t):

returns a stream of zero or one elements depending on whether the value passed is null or not.

iterate():

version that takes three parameters.

gives you the ability to replicate the standard for loop syntax as a stream.

e.g. Stream.iterate(0, i > i < 5, i > i + 1) will give you a stream of Integers from 0 to 4.

Several new sources added:

Java.util.Scanner ( e.g. Stream stream = scanner.tokens() )

Java.util.regex.Matcher ( e.g. Stream stream = matcher.results() )

Optional has a stream() method that returns a stream of zero or one element ( public Stream<T> stream() )

New Stream Features

35

If the Stream is parallel, the lines() method will map the file into memory and assign regions of the file to each thread processing the stream

Parallel Support for Files.lines()

36

What’s New for Javadoc in JDK 9

37

http://download.java.net/java/jdk9/docs/api/overview-summary.html

Provides a search box to the generated API documentation.

Use this search box to find program elements, tagged words, and phrases within the documentation.

Javadoc - JEP 225: Javadoc Search

38

Supports documentation comments in module declarations.

new command-line options to configure the set of modules to be documented and generates a new summary page for any modules being documented.

Javadoc – JEP 261: Module System

39

Supports generating HTML5 output.

To get fully compliant HTML5 output, ensure that any HTML content provided in documentation comments are compliant with HTML5.

Javadoc – JEP 224: HTML5 Javadoc

40

Replace the Doclet API with a simpler design

leverages newer alternative APIs with improved functionality

update the standard doclet to use it

Reformulate the Doclet API to use the Language Model API and DocTree API

Existing Doclet API will be deprecated soon

Javadoc – JEP 221: Simplified Doclet API

41

What’s New for the VM in JDK 9

42

VM enhancements include the following:

JEP 165: Compiler Control

JEP 197: Segmented Code Cache

JEP 276: Dynamic Linking of Language-Defined Object

What’s New for the VM

43

What’s New for JVM Tuning in JDK 9

44

JVM Tuning include the following:

JEP 271: Unified GC Logging

JEP 248: Make G1 the Default Garbage Collector

What’s New for JVM Tuning

45

What’s New in Core Libraries in JDK 9

46

Improves the API for controlling and managing operating system processes.

The ProcessHandle provides:

The process ID: process.getPid()

Arguments

Command

Start time

Accumulated CPU time

User

Parent process

descendants

can also monitor processes' liveness and destroy processes

With the ProcessHandle.onExit method, the asynchronous mechanisms of the CompletableFuture class can perform an action when the process exits.

Core - JEP 102: Process API Updates

47

@Test

public void getPid() throws IOException {

ProcessBuilder builder = new ProcessBuilder("/bin/sleep", "5");

Process proc = builder.start();

assertThat(proc.getPid()).isGreaterThan(0);

}

Core – JEP 102: Process API Improvements - Example

48

Adds further concurrency updates to those introduced in JDK 8 in JEP 155 (Concurrency Updates):

Interoperable publish-subscribe framework: Interfaces supporting the Reactive Streams publish-subscribe framework.

Enhancements to CompletableFuture API: Time-based enhancements:

enable a feature to complete with a value after a certain duration

support for delays,

timeout(),

completeTimeout()

Subclass enhancements to extend CompletableFuture

Javadoc spec rewording

Core - JEP 266: More Concurrency Updates

49

Defines several factory methods (.of(…)) on the List, Set, and Map interfaces for conveniently creating instances of unmodifiable collections and maps with small numbers of elements.

Factory methods added to List interface:

static <E> List<E> of()

static <E> List<E> of(E e1)

static <E> List<E> of(E e1, E e2)

static <E> List<E> of(E e1, E e2, E e3)

static <E> List<E> of(E e1, E e2, E e3, E e4)

static <E> List<E> of(E e1, E e2, E e3, E e4, E e5)

static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6)

static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)

static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)

static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)

static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)

static <E> List<E> of(E... elements)

Core – JEP 269: Convenience Factory Methods for Collections

50

List<String> fruits = List.of("apple", "orange", "banana");

for (String fruit: fruits)

System.out.println(fruit);

try

{

fruits.add("pear");

}

catch (UnsupportedOperationException uoe)

{

System.err.println("unable to modify fruits list");

}

Will output:

apple

orange

banana

unable to modify fruits list

JEP 269: Convenience Factory Methods for Collections - Example

51

@Deprecated annotation provides better information about the status and intended future of APIs:

forRemoval():

This returns a boolean to indicate whether this API element is intended for removal in some future release

E.g. @Deprecated(forRemoval=true) indicates the API will be removed in the next release of the Java SE platform.

Since():

This returns the release or version number, as a string, when this API element was first marked as deprecated

@Deprecated(since="version") contains the Java SE version string that indicates when the API element was deprecated for those deprecated in Java SE 9 and beyond.

E.g. @Deprecated(since="9", forRemoval=true)

New tool, jdeprscan, to scan a class library (JAR file) for uses of deprecated JDK API elements.

Core - JEP 277: Enhanced Deprecation

52

JEP 193: Variable Handles

JEP 254: Compact Strings

JEP 264: Platform Logging API and Service

JEP 268: XML Catalogs

JEP 274: Enhanced Method Handles

JEP 290: Filter Incoming Serialization Data

JEP 259: Stack-Walking API

Core - What’s New in Core Libraries - More

53

What’s New for Internationalization in JDK 9

54

Add support for Unicode 8.0.

JDK 8 supported Unicode 6.2.

The Unicode 6.3, 7.0 and 8.0 standards combined introduced 10,555 characters, 29 scripts, and 42 blocks.

Internationalization - JEP 267 Unicode 8.0

55

Loads properties files in UTF-8 encoding.

UTF-8 is a much more convenient way to represent non-Latin characters.

No more Unicode escapes are required (e.g. \u20AC is Unicode representation for €)

In previous releases:

ISO-8859-1 encoding was used when loading property resource bundles.

provided an escape mechanism for characters that cannot be represented in that encoding

Difficult to use because it requires continuous conversion between its escaped form and text in character encodings that are directly editable.

Can explicitly designate the encoding either ISO-8859-1 or UTF-8, by setting the system property "java.util.PropertyResourceBundle.encoding".

Internationalization - JEP 226: UTF-8 Properties Files

56

Considering a single money property in config.properties file:

money = € / \u20AC

Using JDK 8, this property will be read as:

money = â▯¬ / €

Using JDK 9, this property will be read as:

money = € / €

JEP 226: UTF-8 Properties Files - Example

57

Use locale data from the Unicode Consortium's Common Locale Data Repository (CLDR) by default.

CLDR is the de-facto standard for locale data on many platforms.

Pre-Java 9: need to set system property: java.locale.providers=JRE,CLDR

Java 9: enabled by default

Internationalization – JEP 252 Use CLDR Locale Data

58

http://docs.oracle.com/javase/9/migrate/toc.htm#JSMIG-GUID-5657F44A-B2D7-4FB6-AAD7-295AC4533ABC

supported APIs can be removed from the JDK, but only with advance notice.

Find out if your code is using deprecated APIs by running the static analysis tool jdeprscan.

Prepare for Migration

59

1. Download JDK 9:

https://jdk9.java.net/download/

2. Download Eclipse Oxygen:

http://www.eclipse.org/downloads/packages/release/Oxygen

3. Using Eclipse, patch Eclipse to enable JDK 9 support:

Add the following update site URL:

http://download.eclipse.org/eclipse/updates/4.7-P-builds

4. Add the JDK 9 to Installed JREs:

Window -> Preferences – Java – Installed JREs

How to setup DEV environment in Eclipse

60

Q & A

61