$30 off During Our Annual Pro Sale. View Details »

Java 12 - New features in action

Java 12 - New features in action

In this presentation, we (Jonatan and Marco) investigated the new official and hidden features of Java 12.
We collected code examples and stories behind this release. We were happy about some features and disappointed with others.

We hope that with these slides you can learn quickly and with fun what's coming with the new version of Java.

Marco Molteni

March 18, 2019
Tweet

More Decks by Marco Molteni

Other Decks in Programming

Transcript

  1. Java 12 - CAFE BABE 0000 0038 Java 12 -

    CAFE BABE 0000 0038 Jonatan The JVM Explorer Marco The fullstack guy Missing features Where is Shenandoah? Some Garbage (Collectors) Fun facts Code examples New features and their stories New pitfalls! Release 19.03.2019
  2. Java 12 - CAFE BABE 0000 0038 Jonatan Kaźmierczak •

    Senior consultant at Trivadis • Creator of Class Visualizer • Creator of Maths practice for children • Contributor to JDK projects: Graal, JMC • Has used over 0x10 programming languages • Top-rated contestant in programming, algorithms and data science at HackerRank, Google Code Jam, TopCoder
  3. Java 12 - CAFE BABE 0000 0038 • Freelance Java

    and Angular consultant • Java meetups in ZH … come, share and have fun https://www.meetup.com/Java-Switzerland/ Marco Molteni @marcomolteni https://javaee.ch
  4. Java 12 - CAFE BABE 0000 0038 ToC • Poll

    • Java Enhancement Proposal Overview • Standard library enhancements • JDK 11 or JDK 12? Which distribution?
  5. Java 12 - CAFE BABE 0000 0038 Which Java version

    are you currently using? Version Release 11 09.2018 8 03.2014 < 8 <= 2011 Poll
  6. Java 12 - CAFE BABE 0000 0038 JDK Enhancement Proposal

    (JEP) 189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental) 230: Microbenchmark Suite 325: Switch Expressions (Preview) 326: Raw Literals (Preview) 334: JVM Constants API 340: One AArch64 Port, Not Two 341: Default CDS Archives 344: Abortable Mixed Collections for G1 346: Promptly Return Unused Committed Memory from G1 openjdk.java.net/projects/jdk/12 JEP 12 Click on the JEP link to open its official page.
  7. Java 12 - CAFE BABE 0000 0038 Other improvements (not

    announced) • CompactNumberFormat • String#indent • String#transform • Collectors#teeing • Files#mismatch • HttpsURLConnetion#getSSLConnection • SecureCacheResponse#getSSLSession • CompletionStage#exceptionallyAsync • JShell improvements • Minor improvements (e.g. CHESS Character.UnicodeBlock) • > 650 Bug fixed affecting JDK 11 Discoveries We have found these changes comparing the code source of the JDK 12 and the 11. An easy to use alternative JDK Diff. You can click on the class name to open the JavaDoc. Standard library General
  8. Java 12 - CAFE BABE 0000 0038 JEP Feature Preview

    and Experimental Some features are in ‘Preview’ or ‘Experimental’ status. These features need to be explicitly activated. Status Definition To activate Link Preview The feature is implemented but feedbacks are desired. It could be refined, removed or become permanent in future releases. --enable-preview http://openjdk.jav a.net/jeps/12 Experimental The feature has to mature or the value has still to be determined. Some OpenJDK editors could not include (compilation exclusion) the feature. -XX:+UnlockExperimentalVMOptions (If supported by your JDK) http://openjdk.jav a.net/jeps/82045 56 Disclaimer
  9. Java 12 - CAFE BABE 0000 0038 JEP 326 -

    Raw String Literals (Preview) var json = ` { "name": "OpenJDK", "version": 12 } `; Readable multi-line string without Java indicators. Dropped! Announcement link Already available in: C, C++, C#, Dart, Go, Groovy, Haskell, JavaScript, Kotlin, Perl, PHP, Python, R, Ruby, Scala, Swift and TypeScript
  10. Java 12 - CAFE BABE 0000 0038 String#trasform public interface

    Uppercase { static String wordsCapitalizer(String text) { return Pattern.compile("\\b\\p{L}").matcher(text).replaceAll(m -> m.group().toUpperCase()); } } // New 'feature' "voxxed days zürich".transform(Uppercase::wordsCapitalizer); //-> Voxxed Days Zürich // Good old Java Uppercase.wordsCapitalizer("voxxed days zürich"); //-> Voxxed Days Zürich Raw String Literals leftover It applies a provided function to a String and returns its result. Nothing really new! In a future release, this method could be added to Optional https://bugs.openjdk.java.net/browse/JDK-8214753 In our opinion the code used to motivate the introduction of this feature is unsuitable: https://bugs.openjdk.java.net/browse/JDK-8203703
  11. Java 12 - CAFE BABE 0000 0038 String#trasform - is

    it really needed? Raw String Literals leftover Sources: https://www.mail-archive.com/[email protected]/msg54609.html The mailing list of the core-libs-dev team (JDK) hosted some interesting debates about this feature. Not all the developers were happy with the new method, between the doubts: • the name: some developers were not happy with the choice and how it has been announced (map, process, apply were between the options), the name could not fit with Stream and other objects • the chain method could be a better solution https://bugs.openjdk.java.net/browse/JDK-8140283 • the method is not really useful and limited to String • a cleaner solution to transform/format a String could have been a pipe ‘|>’ like in other languages • with so many open points waiting until release 13 could have been more appropriated “The originating goal was to allow custom alignment methods for those developers not satisfied with String::align()” http://mail.openjdk.java.net/pipermail/c ore-libs-dev/2018-September/055553.h tml Where is String::align?
  12. Java 12 - CAFE BABE 0000 0038 String#indent Limited use

    cases! Raw String Literals leftover Add or remove spaces at the beginning of a String and normalize the end with a ‘\n’. var jsonInner = "'name': 'OpenJDK',\n'version': 12\n" .replace( '\'', '"' ); var jsonOuter = "{\n" + jsonInner.indent( 4 ) + "}\n"; System.out.println( jsonOuter ); { "name": "OpenJDK", "version": 12 } Result Useful to format JSON, XML and code snippets. Added together with String#align to support Raw String Literals; in contrast to RSL and String#align (dopped) it is still in the JDK : https://bugs.openjdk.java.net/browse/JDK-8200435.
  13. Java 12 - CAFE BABE 0000 0038 JEP 325 -

    Switch expression (Preview) - Example Remember to enable the preview mode: jshell --enable-preview String developerRating( int numberOfChildren ) { return switch (numberOfChildren) { case 0 -> "open source contributor"; case 1,2 -> "junior"; case 3 -> "senior"; default -> { if (numberOfChildren < 0) throw new IndexOutOfBoundsException( numberOfChildren ); break "manager"; } }; } developerRating( 0 ); // ==> "open source contributor" developerRating( 4 ); // ==> "manager" Do you notice the differences with the switch statement? Less code verbosity but only preview!
  14. Java 12 - CAFE BABE 0000 0038 // Java 12

    (expression) case 0 -> "free time"; case 1 -> "junior"; JEP 325 - Switch expression (Preview) - Diff No more break; required (for single expressions) Multiple labels with only one case // Java 12 (expression) case 2,3 -> "expert"; // Java 1 (statement) case 2: case 3: "expert"; break; // Java 1 (statement) case 0: "free time"; break; case 1: "junior"; break; This JEP is required by the candidate feature JEP 305 : Pattern Matching for instanceof Extend the switch statement so that it can be used as either a statement or an expression
  15. Java 12 - CAFE BABE 0000 0038 JEP 325 -

    Switch expression (Preview) - Diff 2 Scope of local variables All the cases have to be covered // Java <12 (statement) ... not enforced ... // Java <12 - statement // switch block scope case 0: int a = 123; break; case 1: int a = 345; break; // ERROR! // Java 12 - expression // case block scope case 0 -> {int a = 123; break a;} case 1 -> {int a = 345; break a;} // Java 12 (expression) case 0 -> "Value found"; // Compilation error if default not present default -> throw new IllegalStateException(); break statement to return a value from a block scope // Java <12 (statement) ... not applicable ... // Java 12 - expression case 0 -> {break "Result here";}
  16. Java 12 - CAFE BABE 0000 0038 Compact Number Format

    - Short Bugs! Debatable scope! Unicode Standard import java.text.*; var cnf = NumberFormat.getCompactNumberInstance(); cnf.format( 1_000 ); // ==> 1K cnf.format( 1_920 ); // ==> 2K - instead of 1.9K cnf.format( 1_000_000 ); // ==> 1M cnf.format( 1L << 30 ); // ==> 1B cnf.format( 1L << 40 ); // ==> 1T cnf.format( 1L << 50 ); // ==> 1126T This new feature implements the Unicode Compact Number Format: https://unicode.org/reports/tr35/tr35-numbers.html#Compact_Number_Formats According to Unicode: “The short format is designed for UI environments where space is at a premium, and should ideally result in a formatted string no more than about 6 em wide”.
  17. Java 12 - CAFE BABE 0000 0038 Compact Number Format

    - Long Unicode Standard import java.text.*; var cnf = NumberFormat.getCompactNumberInstance( Locale.GERMAN, NumberFormat.Style.LONG ); cnf.format( 1_000 ); // ==> 1 Tausend cnf.format( 1_000_000 ); // ==> 1 Million cnf.format( 2_000_000 ); // ==> 2 Million (!) - instead of 2 Millionen cnf.format( 17_000_000 ); // ==> 17 Millionen cnf.format( 1L << 30 ); // ==> 1 Milliarde cnf.format( 1L << 31 ); // ==> 2 Milliarde (!) - instead of 2 Milliarden cnf.format( 1L << 34 ); // ==> 17 Milliarden cnf.format( 1L << 40 ); // ==> 1 Billion cnf.format( 1L << 41 ); // ==> 2 Billion (!) - instead of 2 Billionen cnf.format( 1L << 50 ); // ==> 1126 Billionen The long variant of the compact number format contains mistakes. Before using this feature check if the problem has been corrected!
  18. Java 12 - CAFE BABE 0000 0038 Compact Number Format

    - Swiss edition Unicode Standard { "long.CompactNumberPatterns", new String[] { "", "", "", "0 Tausend", "00 Tausend", "000 Tausend", "0 Million", "00 Millionen", "000 Millionen", "0 Milliarde", "00 Milliarden", "000 Milliarden", "0 Billion", "00 Billionen", "000 Billionen", } }, FormatData_de.java FormatData_fr.java { "long.CompactNumberPatterns", new String[] { "", "", "", "0 millier", "00 mille", "000 mille", "0 million", "00 million", "000 million", "0 milliard", "00 milliard", "000 milliard", "0 billion", "00 billion", "000 billion", } }, { "long.CompactNumberPatterns", new String[] { "", "", "", "0 mille", "00 mila", "000 mila", "0 milione", "00 milioni", "000 milioni", "0 miliardo", "00 miliardi", "000 miliardi", "0 mille miliardi", "00 mila miliardi", "000 mila miliardi", } }, FormatData_it.java Here the values used in German, French and Italian. There are errors and the implementation pattern is inadequate. There is no Rumantsch version. FormatData_rm.java ?
  19. Java 12 - CAFE BABE 0000 0038 Files#mismatch Different content

    FileOne: ‘abcdef’ FileTwo: ‘abcd1f’ Same content FileOne: ‘abcdef’ FileTwo: ‘abcdef’ result = 4L result = -1L Different file size (encoding) FileOne: ‘Zürich’ FileTwo: ‘Zürich’ result = 1L (size of the file) Non existing file Files.mismatch (Paths.get(“null”), Paths.get(“null”)) -1L var result = Files.mismatch(pathFileOne, pathFileTwo); Nice but … watch out! /** * Finds and returns the position of the first mismatched byte in the content * of two files, or -1L if there is no mismatch.[...] */
  20. Java 12 - CAFE BABE 0000 0038 Collector#teeing - Example

    It collects a Stream using two independent collectors. The results are merged using a BiFunction Interesting small update. 'XX' Conferences: [Devoxx, Voxxed Days] 'One' Conferences: [Code One, Basel One] result var result = Stream.of("Devoxx", "Voxxed Days", "Code One", "Basel One") .collect(Collectors.teeing( // first collector Collectors.filtering(n -> n.contains("xx"), Collectors.toList()), // second collector Collectors.filtering(n -> n.endsWith("One"), Collectors.toList()), // merger - automatic type inference doesn't work here (List<String> list1, List<String> list2) -> List.of(list1, list2) )); System.out.println("'XX' Conferences: " + result.get(0)); System.out.println("'One' Conferences: " + result.get(1));
  21. Java 12 - CAFE BABE 0000 0038 Collectors teeing -

    Fun facts The etymology of teeing can help us to remember the name during our daily activity or to show our knowledge at the workplace. Teeing is originated from the plumbing tee! Wikipedia: ‘A tee, the most common pipe fitting, is used to combine (or divide) fluid flow.’ Linux has the tee command that splits the data! Among the authors we find Richard Stallman. Other names proposed for this feature: bisecting, duplexing, bifurcate, replicator, fanout, tapping, unzipping, tapping, collectionToBothAndThen, biCollecting, expanding, forking, etc. http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-June/053987.html
  22. Java 12 - CAFE BABE 0000 0038 JEP 334 -

    JVM Constants API Class Visualizer generated diagrams Could be confusing. Don’t be surprised if your IDE will suggest these new methods: describeConstable, resolveConstantDesc. If you don’t work with constant pools ignore them. Constant pools documentation
  23. Java 12 - CAFE BABE 0000 0038 Constable#describeConstable and #resolveConstantDesc

    JEP 334 - JVM Constants API public interface Constable { /** * Returns an {@link Optional} containing the nominal descriptor for this * instance, if one can be constructed, or an empty {@link Optional} * if one cannot be constructed. [...] **/ Optional<? extends ConstantDesc> describeConstable(); } "Java 12".describeConstable(); // ==> Optional[Java 12] Example Not relevant for most of the devs. public interface ConstantDesc { /** * @param lookup The {@link MethodHandles.Lookup} to provide name resolution * and access control context * @return the resolved constant value [...] */ Object resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException; } "Java 12".resolveConstantDesc( null ); // ==> "Java 12" Example
  24. Java 12 - CAFE BABE 0000 0038 JEP 189 -

    Shenandoah (Experimental) Ultra-low pause, async GC. It doesn’t require a Full GC cycle. Great for containers and cloud. Disabled in Oracle builds... Shenandoah … but in RedHat builds since JDK 8 https://wiki.openjdk.java.net/display/shenandoah/Main Latency distribution
  25. Java 12 - CAFE BABE 0000 0038 JEP 189 -

    Shenandoah - Where to find it? $ java -XX:+UseShenandoahGC -version openjdk version "1.8.0_191" OpenJDK Runtime Environment (build 1.8.0_191-b12) OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode) In Red Hat Enterprise Linux OpenJDK since v1.8.0 and production ready! $ java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -verbose:gc -version [0.005s][info][gc] Using Shenandoah openjdk version "12" 2019-03-19 OpenJDK Runtime Environment (build 12+33-Debian-1) OpenJDK 64-Bit Server VM (build 12+33-Debian-1, mixed mode, sharing) In Debian as experimental. $ java -XX:+UseShenandoahGC Error: VM option 'UseShenandoahGC' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions. $ java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC Error occurred during initialization of VM Option -XX:+UseShenandoahGC not supported Oracle builds don’t support it. https://bugs.openjdk.java. net/browse/JDK-8215030
  26. Java 12 - CAFE BABE 0000 0038 JEP 189 -

    Shenandoah - In depth Only for GC hackers The most detailed and technical presentation of Shenandoah is from Aleksey Shipilëv (Red Hat), the author of this GC. https://shipilev.net/talks/ javazone-Sep2018-shenandoah.pdf For starters Excellent GC introduction by Jelastic. They initiated and contributed to JEP 346. https://www.slideshare.net/jelastic/ elastic-jvm-automatic-vertical-scaling-of-the-java-heap
  27. Java 12 - CAFE BABE 0000 0038 Shenandoah has already

    similar features (experimental): -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay JEP 346 - Promptly Return unused committed memory from G1 • Improve GC in containers • VM should detect phases of heap under-utilization to reduce the heap usage during this phase Feature initiated by Ruslan Synytsky (Jelastic) and Rodrigo Bruno (http://www.inesc-id.pt/). Improvement in heap usage! Containers focus!
  28. Java 12 - CAFE BABE 0000 0038 With the new

    approach the G1 stops and splits the collection if the amount of work required to collect live objects from the collection set exceeds the configured pause time limit. Previously, G1 had to collect all the live objects in a collection set without stopping. JEP 344 - Abortable Mixed Collection for G1 • Introduces G1 collection pauses of configured/predictable length • Increases the application throughput Improvements in G1 efficiency.
  29. Java 12 - CAFE BABE 0000 0038 • Announced improvement

    of the startup time through the creation of a classes’ metadata list shared between JVM processes • In previous versions java -Xshare:dump was required. dump generates jre/lib/server/classes.jsa binary file with the metadata • JEP 341 - Default Class Data Sharing Archive CDS records in a file the classes’ metadata to use it with the JVM. It is possible to include the application classpath since JEP 310 (Java 10). The improvement could be noticeable in particular scenarios with multiple JVMs sharing the same metadata. CDS documentation. An informative article https://blog.codefx.org/java/application-class-data-sharing/ No noticeable improvement in modern scenarios Is it still relevant in a docker / kubernetes / microservices world?
  30. Java 12 - CAFE BABE 0000 0038 JEP internal JDK

    changes • 230: Microbenchmark tools for JDK “Add a basic suite of microbenchmarks to the JDK source code, and make it easy for developers to run existing microbenchmarks and create new ones.” • 340: One AArch64 Port “Remove all of the sources related to the arm64 port while retaining the 32-bit ARM port and the 64-bit aarch64 port.” Not relevant to us developers!
  31. Java 12 - CAFE BABE 0000 0038 Quo vadis JDK

    Mission Control 7? • Promised final RC date: 02.01.2019 • Still in Early-Access phase • All previous downloads removed: http://jdk.java.net/jmc/ • There are many unresolved issues, including the one reported by Jonatan: https://bugs.openjdk.java.net/browse/JMC-6195?jql=proje ct%20%3D%20JMC Promised … Not delivered! Missing leftover from JDK 11
  32. Java 12 - CAFE BABE 0000 0038 Which JDK ?

    12 - rel. train ❏ Small new features ❏ 6 months of bug fixes ❏ 650 bug fixes ❏ JShell improvements ❏ Full backward compatibility ❏ GC improvements. Focus on containers and cloud! ❏ Test future LTS features 11 - LTS ❏ Follow LTS releases (11 -> 17) ❏ Framework/Server dependency ❏ Production environments
  33. Java 12 - CAFE BABE 0000 0038 So many options

    … choose your OpenJDK! Name / Editor Link Oracle jdk.java.net/12/ RedHat developers.redhat.com/products/openjdk Open J9 / Eclipse www.eclipse.org/openj9 Corretto / Amazon aws.amazon.com/corretto/ Zulu / Azul www.azul.com/ AdoptOpenJDK / IBM, Clarity, etc. adoptopenjdk.net SapMachine / SAP sap.github.io/SapMachine/ Linux distribution Linux distribution You Your laptop Excellent info here: https://medium.com/@javachampions/java-is-still-free-2-0-0-6b9aa8d6d244
  34. Java 12 - CAFE BABE 0000 0038 Q&A What’s this

    thing? Coffee? Guess and check in the last slide! Jonatan’s GitHub, with more examples and tech details: https://github.com/jonatan-kazmierczak/ java-new-features/ Java Zurich Meetup: https://www.meetup.com/Java-Switzerland/ Marco’s blog and twitter: https://javaee.ch @marcomolteni Links
  35. Java 12 - CAFE BABE 0000 0038 https://en.wikipedia.org/wiki/Java_class_file JSR 202

    Java 12 = Class Format Version 56 (0x38 hex) Compiled Java classes start with a magic number in hex: CAFE BABE followed by the minor version number of the class file major version number of the class file. Java 12 will have the major version of class format = 56. Remember it if you see: Exception in thread "main" java.lang.UnsupportedClassVersionError: Example has been compiled by a more recent version of the Java Runtime (class file version 56.0), this version of the Java Runtime only recognizes class file versions up to 55.0 > hexdump -C Example.class 00000000 ca fe ba be 00 00 00 38 00 1c 0a 00 06 00 0e 09 |.......7........| 00000010 00 0f 00 10 08 00 11 0a 00 12 00 13 07 00 14 07 |................| 00000020 00 15 01 00 06 3c 69 6e 69 74 3e 01 00 03 28 29 |.....<init>...()| 00000030 56 01 00 04 43 6f 64 65 01 00 0f 4c 69 6e 65 4e |V...Code...LineN| 00000040 75 6d 62 65 72 54 61 62 6c 65 01 00 04 6d 61 69 |umberTable...mai| 00000050 6e 01 00 0a 53 6f 75 72 63 65 46 69 6c 65 01 00 |n...SourceFile..| 00000060 0c 45 78 61 6d 70 6c 65 2e 6a 61 76 61 0c 00 07 |.Example.java...|