Java 9 has finally arrived and brings a lot of new features - 91 JEPs!
This presentation details the main features of Java 9, excluding the Java Module System, which will be detailed in a future presentation.
The main arguments are:
• jshell (the REPL interface)
• Ahead-of-time compiler (AOTC)
• G1 garbage collector (promoted to default GC)
• Javadoc improvements
• Multi-Release jars
• Private methods in interfaces
• New API (VarHandle, Flow, Collection and Stream, StackWalker, Process)
The presentation also highlights the most common problems (and there are many) that you may encounter while updating to Java 9 for your builds and for running your applications.
3. sbordet@webtide.com
Java 9 Agenda
● Java 9 Introduction
● Java 9 Changes and New Features
○ Not Jigsaw Modules
● Java 9 Migration
● Open Discussion
4. sbordet@webtide.com
Java 9
● Java 9 comes with a MASSIVE number of changes
○ 91 JEPs (!)
● Biggest change: Jigsaw modules
○ Come to the next meeting :)
● Upgrade to Java 9 not as smooth as past JDKs
○ Needs very thorough testing
5. sbordet@webtide.com
Java 9
●
Java 9 is NOTa Long Term Support (LTS) Release
● Java 8 current LTS Release supported March 2014 - January 2019
● Java 9 supported September 2017 - March 2018
● Java 10 supported March 2018 - September 2018
● Java 11 new LTS Release September 2018 - September 2021
7. sbordet@webtide.com
Java 9 Removals
● Removed endorsed directory mechanism
$JAVA_HOME/lib/endorsed
● Could only contain updates for:
○ CORBA
○ XML DOM
○ XML SAX
● Rarely used to update the implementations shipped with the JDK
10. sbordet@webtide.com
Java 9 Changes
● ClassLoading Implementation Changes
// Throws ClassCastException now!
URLClassLoader system = (URLClassLoader)ClassLoader.getSystemClassLoader();
● ClassLoader Resources
URL resource = system.getResource("java/lang/String.class");
resource = jrt:/java.base/java/lang/String.class
● Class scanning for annotations
○ Previous techniques not working in JDK 9
○ Cannot retrieve the list of jars to open
11. sbordet@webtide.com
Java 9 Changes
● JEP 223 - New Version String Scheme
○ System.getProperty("java.version")
○ 1.8.0_152 -> 9.0.1
○ Broke many Maven Plugins, Jetty, etc.
● JDK 9’s java.lang.Runtime.Version class
○ Cannot parse JDK 8 version string
○ Must implement custom parsing to support both
12. sbordet@webtide.com
Java 9 New Features
● JEP 260 - Encapsulate Internal APIs
● Non-critical internal APIs have been removed
○ sun.misc.Base64Decoder
● Critical internal APIs without replacement -> retained
○ In module jdk.unsupported
○ For example, sun.misc.Unsafe
○ Don’t use them
● Critical internal APIs with replacement -> encapsulated
○ Use the replacements
13. sbordet@webtide.com
Java 9 New Features
● JEP 260 - Encapsulate Internal APIs
● Most internal APIs now have a public replacement
● Finalization
○ sun.misc.Cleaner replaced by java.lang.ref.Cleaner
○ Object.finalize() is now deprecated
● Unsafe access
○ Some sun.misc.Unsafe usage replaced by VarHandle
14. sbordet@webtide.com
Java 9 New Features
● JEP 260 - Encapsulate Internal APIs
● jdeps tool produces a report of class/jar/module dependencies
$ jdeps -s jetty-util-9.4.8-SNAPSHOT.jar
jetty-util-9.4.8-SNAPSHOT.jar -> java.base
jetty-util-9.4.8-SNAPSHOT.jar -> java.desktop
jetty-util-9.4.8-SNAPSHOT.jar -> java.logging
jetty-util-9.4.8-SNAPSHOT.jar -> java.naming
jetty-util-9.4.8-SNAPSHOT.jar -> java.sql
jetty-util-9.4.8-SNAPSHOT.jar -> java.xml
jetty-util-9.4.8-SNAPSHOT.jar -> not found
15. sbordet@webtide.com
Java 9 New Features
● JEP 247 - Compile for older platforms
● New switch --release to javac
○ Supports up to 3 previous releases
● $JAVA_HOME/lib/ct.sym
○ Zipped file containing the symbols for each platform
17. sbordet@webtide.com
Java 9 New Features
● JEP 238 - Multi Release jars
com/
acme/
A.class
B.class
C.class
META-INF/
versions/
9/
com/
acme/
A.class
D.class
18. sbordet@webtide.com
Java 9 Changes
● URLStreamHandler
● Java 8: Magic Reflection
○ sun.net.www.protocol.<scheme>.Handler
● Java 9: ServiceLoader
○ Implement java.net.spi.URLStreamHandlerProvider
● Difficult to make a jar with both solutions
○ Service files cannot be versioned
19. sbordet@webtide.com
Java 9 New Features
● JEP 213 - Small Language Changes
● Cannot use "_" as identifier
○ Object _ = new Object();
● Improved type inference
○ Use diamond notation in anonymous inner classes
● Private methods in interfaces
○ Useful to AOP frameworks
○ Avoids code duplications in default methods
20. sbordet@webtide.com
Java 9 New Features
● JEP 213 - Small Language Changes
● Enhanced try-with-resources
InputStream input = ...;
...
try (input) {
...
}
21. sbordet@webtide.com
Java 9 New Features
● JEP 264 - Platform Logging APIs
○ Implementation defaults to java.util.logging
System.getLogger("name")
.log(Level.INFO, () -> "a" + " - " + "b");
System.getLogger("name")
.log(Level.INFO, "%s - %s", a, b);
22. sbordet@webtide.com
Java 9 New Features
● JEP 254 - Compact Strings
○ java.lang.String now stores a byte[], not a char[]
● JEP 280 - String concatenation using invokedynamic
○ Faster and allocates less
● JEP 269 - Collections factory methods
○ Space efficient
List.of("a", "b", "c");
Set.of("a", "b", "c");
Map.of("a", 1, "b", 2, "c", 3);
23. sbordet@webtide.com
Java 9 New Features
● JEP 193 - Variable Handles
class ConcurrentLinkedQueue_BAD {
AtomicReference<Node> head; // BAD, adds indirection
}
class ConcurrentLinkedQueue {
Node head;
private static final VarHandle HEAD;
static {
HEAD = MethodHandles.lookup()
.findVarHandle(ConcurrentLinkedQueue.class, "head", Node.class);
}
public void m() {
if (HEAD.compareAndSet(...))
...
}
}
24. sbordet@webtide.com
Java 9 New Features
● JEP 102 - Process API
Process p = new ProcessBuilder()
.command("java")
.directory(new File("/tmp"))
.redirectOutput(Redirect.DISCARD)
.start();
ProcessHandle.of(p.pid())
.orElseThrow(IllegalStateException::new)
.onExit()
.thenAccept(h ->
System.err.printf("%d exited%n", h.pid())
);
25. sbordet@webtide.com
Java 9 New Features
● JEP 102 - Process API
Optional<Duration> cpuTimeOpt = ProcessHandle.current().info()
.totalCpuDuration();
long cpuTime = cpuTimeOpt
.map(duration -> duration.toNanos())
.orElse(-1L);
26. sbordet@webtide.com
Java 9 New Features
● JEP 266 - Concurrent APIs Enhancements
● java.util.concurrent.Flow
○ Identical API and semantic of ReactiveStreams
● CompletableFuture Enhancements
○ Common scheduler for timeout functionalities
CompletableFuture.supplyAsync(() -> longJob())
.completeOnTimeout("N/A", 1, TimeUnit.SECONDS)
CompletableFuture.supplyAsync(() -> longJob())
.orTimeout(1, TimeUnit.SECONDS)
27. sbordet@webtide.com
● JEP 143 - Improve Contended Locking
○ synchronized now as scalable as java.util.concurrent.Lock
http://vmlens.com/articles/performance-improvements-of-java-monitor/
Java 9 Changes
28. sbordet@webtide.com
Java 9 New Features
● JEP 295: Ahead-of-Time Compilation
○ Experimental
○ Based on the Java-based Graal JIT compiler
https://mjg123.github.io/2017/10/02/JVM-startup.html
29. sbordet@webtide.com
Java 9 New Features
● JEP 222 - jshell Read-Eval-Print-Loop (REPL)
○ Can be accessed programmatically via module jdk.jshell
● Pretty powerful !
○ Completion
○ Imports
○ Variable creation
○ Documentation
○ Functions and Forward References
○ History
○ Search
○ External Editor
30. sbordet@webtide.com
Java 9 Changes
● JEP 248 - Make G1 the Default Collector
● 250+ Improvements
○ Adaptive start of concurrent mark -XX:+G1UseAdaptiveIHOP
○ Made internal data structures more concurrent
○ More phases parallelized
○ Reduced contention
○ Reduced memory consumption
○ …
● 180+ Bug Fixes
31. sbordet@webtide.com
Java 9 Changes
● JEP 158 - Unified JVM Logging
● Logs have a message, tags (finally) and a level; can be decorated
● Tags
○ gc, ref, ergo, …
● Levels
○ error, warning, info, debug, trace
● Output
○ stdout, stderr, file
● Decorators
○ time (various formats), pid, tid, level, tags
● Default
○ -Xlog:all=warning:stderr:uptime,level,tags
32. sbordet@webtide.com
Java 9 Changes
● JEP 271 - Unified GC Logging
○ Done using JEP 158 - Unified JVM Logging
● Example for GC logging
○ -Xlog:gc*,ergo*=trace,ref*=debug:file=logs/gc.log:time,level,tags
● Not compatible with previous logging formats
○ Need to parse the logs differently
34. sbordet@webtide.com
Java 9 Changes
● JEP 277 - Enhanced Deprecation
@Deprecated(since="1.8", forRemoval=true)
● jdeprscan
○ Produces a report of deprecations
35. sbordet@webtide.com
Java 9 Changes
● JEP 229 - Keystore Defaults to PKCS12
● PKCS12
○ Standard format, more secure, more extensible
○ Already supported in JDK 8
● JDK 9
○ keytool by default creates PKCS12 keystores
○ Autodetects JKS and PKCS12 keystores
36. sbordet@webtide.com
Java 9 New Features
● JEP 219 - Datagram Transport Layer Security (DTLS)
● JEP 244 - TLS Application-Layer Protocol Negotiation Extension (ALPN)
● JEP 246 - Leverage CPU Instructions for GHASH and RSA
● JEP 249 - OCSP Stapling for TLS
● JEP 273 - DRBG-Based SecureRandom Implementations
● JEP 287 - SHA-3 Hash Algorithms
● JEP 288 - Disable SHA-1 Certificates
37. sbordet@webtide.com
Java 9 Migration
● Migrating to Java 9 is an iterative process
○ Typically cannot be done in one step only
● Update dependencies
● Run jdeps -jdkinternals
● Fix usages of encapsulated APIs
● Using EE modules ?
● Add --add-modules to command line
38. sbordet@webtide.com
Java 9 Migration
● Update command line options
● Fix GC logging
● Fix your System.getProperty("java.version") usages
● Do not do deep reflection on JDK classes
○ Do not use setAccessible(true);
● Verify your ClassLoader usages
● Verify your sun.* usages
39. sbordet@webtide.com
Migrating OWNER to Java 9
Problems migrating OWNER:
1. Options removed from command line tools (javac, java,etc)
2. Some classes and packages have been removed
○ I.e. java.lang.NoClassDefFoundError:
javax/xml/bind/DatatypeConverter
3. Problems with some libraries and maven plugins not ready for JDK 9
→ update/drop these dependencies.
4. Some jdk classes have been improved and expose some internal
changes (Hashtable.toString() → failing tests).
40. sbordet@webtide.com
Migrating OWNER to Java 9
5. Custom URLStreamHandlers changed. → Multi release jar →
reimplement url loading mechanism in OWNER itself.
6. Some reflection API changed (Invoking default methods on
Interfaces): MethodHandles.Lookup.unreflectSpecial() → using new
API for JDK9
7. Mockito 1.x is not Java9 ready → port tests to Mockito 2.x (work in
progress)
Problems migrating OWNER:
Options removed from command line tools (javac, java)
Source/Target option 1.5 is no longer supported → You need to use jdk 6 or later (and drop jdk 5 support).
Some classes and packages have been removed
I.e. java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter I was using that class for Base64 encoding, so I needed to remove the dependency to javax.xml.bind package and implement a Base64 class that works from JDK 6 to 9 using available classes on the specific JDK.
Problems with some libraries and maven plugins not ready for JDK 9 → update/drop these dependencies.
New dependencies → new rules → new problems :) (i.e. maven-jar-plugin useDefaultManifestFile has been deprecated, and now just makes the build fail)
Some jdk classes have been improved and expose some internal changes. I.e. in Hashtable some method behave differently (toString order of properties is different, some unit tests were failing)
Custom URLStreamHandlers changed. → Multi release jar → reimplement url loading mechanism in OWNER itself.
Multi release jar (pom.xml changes ok... but most IDE can have issues: different source folders using different source/target to compile → IDE can’t tell you if you are using missing classes/etc.)
Dropped the mechanism used and re-implemented internally.
Some reflection API changed (Invoking default methods on Interfaces): MethodHandles.Lookup.unreflectSpecial() → using new API for JDK9
Mockito 1.x is not Java9 ready → port tests to Mockito 2.x (work in progress)