So, you wanna
migrate to Java9?
by Tomek Adamczewski
13/11/2017
Where are we?
2
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
Cool features of Java 9
• Project Jigsaw
• JShell
• Enhanced Collections framework
• Enhanced @Deprecated
• Project Coin improvements
• Support for cgroup limits (think: docker)
• G1GC improvements
• Changes to JDK Release Model
3
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
“Think trains, not limousines”
4
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
5
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017 Definition of Done
• Code compiles
• New features merged to the master branch
• All tests pass
• The task is documented and closed
1
6
Code
Compiles
jig·saw [jig-saw] n.
a complicated problem consisting of many
different parts
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
There are no silver bullets
A lot of libraries or plugins are not compatible with Java 9 yet
7
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
Useful tools
$ jdeps --jdk-internals -R --class-path ‘lib/*’ guava-HEAD-jre-SNAPSHOT.jar
split package: javax.annotation [jrt:/java.xml.ws.annotation, lib/jsr305-1.3.9.jar]
guava-HEAD-jre-SNAPSHOT.jar -> jdk.unsupported
com.google.common.cache.Striped64 -> sun.misc.Unsafe
JDK internal API (jdk.unsupported)
com.google.common.cache.Striped64$1 -> sun.misc.Unsafe
JDK internal API (jdk.unsupported)
(…)
JDK Internal API Suggested Replacement
---------------- ---------------------
sun.misc.Unsafe See http://openjdk.java.net/jeps/260
8
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
…and hacks
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
- <source>1.8</source>
- <target>1.8</target>
+ <source>9</source>
+ <target>9</target>
+ <compilerArgs>
+ <arg>--add-exports</arg>
+ <arg>java.base/sun.security.jca=ALL-UNNAMED</arg>
+ </compilerArgs>
</configuration>
9
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
…and hacks
java
① --add-opens java.base/java.lang=ALL-UNNAMED
② --add-modules java.xml.ws.annotation
③ --patch-module java.xml.ws.annotation=jsr305-3.0.2.jar
--class-path $dependencies
-jar $appjar
10
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
2
11
Code Compiles
New keyword
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
JEP 302: Lambda Leftovers
Treatment of underscores
In many languages, it is common to use an underscore (_) to denote an unnamed
lambda parameter (and similarly for method and exception parameters):
(…)
Phase 2 came in Java 9, when this warning became an error.
12
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
BiFunction<Integer, String, String> biss = (i, _) -> String.valueOf(i);
Sonar to the rescue!™
13
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
Yet another tool to cope with?
14
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
…not really!
15
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
3
16
New feature merged
to the master branch
Things might fail or
they might not fail
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
Enhanced Collections framework
static <K,V> Map<K,V> of()
static <K,V> Map<K,V> of(K k1, V v1)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10)
static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)
17
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
Map<String, Integer> fooBar = Map.ofEntries(
entry("foo", 1),
entry("bar", 2),
// (...)
entry("baz", 42));
We’ve all done it before, didn’t we?
@SafeVarargs
public static <K, V> Map<K, V> map(Entry<K, ? extends V>... entries) {
return stream(entries)
.filter(Objects::nonNull)
.collect(toMap(Entry::getKey, Entry::getValue));
}
18
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
private static final Map<String, ErrorReason> ERROR_REASON_MAPPER =
map(
entry("1001", Format_Incorrect),
entry("1002", Format_Expiry_Date_Incorrect),
// 95 more entries
entry(”6027", Entity_Already_Active));
19
Case studyConfidential/Restricted/Public
Presentationorparttitle
13/11/2017
----------------------------------
BUILD SUCCESS
----------------------------------
Total time: 01:08 min (Wall Clock)
20
Case studyConfidential/Restricted/Public
Presentationorparttitle
13/11/2017
private static final Map<String, ErrorReason> ERROR_REASON_MAPPER =
MapUtils.<String, ErrorReason>map( //explicit generics improve compile time by ~50s
entry("1001", Format_Incorrect),
entry("1002", Format_Expiry_Date_Incorrect),
// 95 more entries
entry(”6027", Entity_Already_Active));
----------------------------------
BUILD SUCCESS
----------------------------------
Total time: 10.556 s (Wall Clock)
Jenkins build-timeout plugin
21
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
Possible strategies
• Absolute
• Deadline
• Elastic
• Likely stuck
• No Activity
Possible actions
• Abort
• Fail
• Abort and restart
• Write build description
4
22
All tests pass
Things might fail…
but they also might not fail
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
OptUtils
/** @return ofNullable(t).map(provider).orElseGet(supplier) */
public static <T, R> R optGet(
T t,
Function<T, R> provider,
Supplier<R> supplier) {
return ofNullable(t).map(provider).orElseGet(supplier);
}
23
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
You can “unit” test your performance
@Test
public void testPerf() throws Exception {
Result result = benchmark(4, 1000,
(thread, pass) -> singlePass(thread, pass));
LOG.info(Table.print(result));
assertExecTimes(result);
}
24
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
Ugly? But it’s up to 10x faster…
/** @return ofNullable(t).map(provider).orElseGet(supplier) */
public static <T, R> R optGet(
T t,
Function<T, R> provider,
Supplier<R> supplier) {
return t == null ?
supplier.get() :
optGet(provider.apply(t), supplier);
}
/** @return ofNullable(t).orElseGet(supplier) */
public static <T> T optGet(T t, Supplier<T> supplier) {
return t == null ? supplier.get() : t;
}
25
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
5
26
The task is documented
and closed
In case you just woke up…
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
Brace yourself
Java WILL be updated every 6 months. Make sure you’re armed and ready
27
Confidential/Restricted/Public
Presentationorparttitle
13/11/2017
CONTACT
tomasz.adamczewski@idemia.com

So, you wanna migrate to Java 9?

  • 1.
    So, you wanna migrateto Java9? by Tomek Adamczewski 13/11/2017
  • 2.
  • 3.
    Cool features ofJava 9 • Project Jigsaw • JShell • Enhanced Collections framework • Enhanced @Deprecated • Project Coin improvements • Support for cgroup limits (think: docker) • G1GC improvements • Changes to JDK Release Model 3 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 4.
    “Think trains, notlimousines” 4 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 5.
    5 Confidential/Restricted/Public Presentationorparttitle 13/11/2017 Definition ofDone • Code compiles • New features merged to the master branch • All tests pass • The task is documented and closed
  • 6.
    1 6 Code Compiles jig·saw [jig-saw] n. acomplicated problem consisting of many different parts Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 7.
    There are nosilver bullets A lot of libraries or plugins are not compatible with Java 9 yet 7 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 8.
    Useful tools $ jdeps--jdk-internals -R --class-path ‘lib/*’ guava-HEAD-jre-SNAPSHOT.jar split package: javax.annotation [jrt:/java.xml.ws.annotation, lib/jsr305-1.3.9.jar] guava-HEAD-jre-SNAPSHOT.jar -> jdk.unsupported com.google.common.cache.Striped64 -> sun.misc.Unsafe JDK internal API (jdk.unsupported) com.google.common.cache.Striped64$1 -> sun.misc.Unsafe JDK internal API (jdk.unsupported) (…) JDK Internal API Suggested Replacement ---------------- --------------------- sun.misc.Unsafe See http://openjdk.java.net/jeps/260 8 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 9.
    …and hacks <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> - <source>1.8</source> -<target>1.8</target> + <source>9</source> + <target>9</target> + <compilerArgs> + <arg>--add-exports</arg> + <arg>java.base/sun.security.jca=ALL-UNNAMED</arg> + </compilerArgs> </configuration> 9 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 10.
    …and hacks java ① --add-opensjava.base/java.lang=ALL-UNNAMED ② --add-modules java.xml.ws.annotation ③ --patch-module java.xml.ws.annotation=jsr305-3.0.2.jar --class-path $dependencies -jar $appjar 10 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 11.
  • 12.
    JEP 302: LambdaLeftovers Treatment of underscores In many languages, it is common to use an underscore (_) to denote an unnamed lambda parameter (and similarly for method and exception parameters): (…) Phase 2 came in Java 9, when this warning became an error. 12 Confidential/Restricted/Public Presentationorparttitle 13/11/2017 BiFunction<Integer, String, String> biss = (i, _) -> String.valueOf(i);
  • 13.
    Sonar to therescue!™ 13 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 14.
    Yet another toolto cope with? 14 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 15.
  • 16.
    3 16 New feature merged tothe master branch Things might fail or they might not fail Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 17.
    Enhanced Collections framework static<K,V> Map<K,V> of() static <K,V> Map<K,V> of(K k1, V v1) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3) static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries) 17 Confidential/Restricted/Public Presentationorparttitle 13/11/2017 Map<String, Integer> fooBar = Map.ofEntries( entry("foo", 1), entry("bar", 2), // (...) entry("baz", 42));
  • 18.
    We’ve all doneit before, didn’t we? @SafeVarargs public static <K, V> Map<K, V> map(Entry<K, ? extends V>... entries) { return stream(entries) .filter(Objects::nonNull) .collect(toMap(Entry::getKey, Entry::getValue)); } 18 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 19.
    private static finalMap<String, ErrorReason> ERROR_REASON_MAPPER = map( entry("1001", Format_Incorrect), entry("1002", Format_Expiry_Date_Incorrect), // 95 more entries entry(”6027", Entity_Already_Active)); 19 Case studyConfidential/Restricted/Public Presentationorparttitle 13/11/2017 ---------------------------------- BUILD SUCCESS ---------------------------------- Total time: 01:08 min (Wall Clock)
  • 20.
    20 Case studyConfidential/Restricted/Public Presentationorparttitle 13/11/2017 private staticfinal Map<String, ErrorReason> ERROR_REASON_MAPPER = MapUtils.<String, ErrorReason>map( //explicit generics improve compile time by ~50s entry("1001", Format_Incorrect), entry("1002", Format_Expiry_Date_Incorrect), // 95 more entries entry(”6027", Entity_Already_Active)); ---------------------------------- BUILD SUCCESS ---------------------------------- Total time: 10.556 s (Wall Clock)
  • 21.
    Jenkins build-timeout plugin 21 Confidential/Restricted/Public Presentationorparttitle 13/11/2017 Possiblestrategies • Absolute • Deadline • Elastic • Likely stuck • No Activity Possible actions • Abort • Fail • Abort and restart • Write build description
  • 22.
    4 22 All tests pass Thingsmight fail… but they also might not fail Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 23.
    OptUtils /** @return ofNullable(t).map(provider).orElseGet(supplier)*/ public static <T, R> R optGet( T t, Function<T, R> provider, Supplier<R> supplier) { return ofNullable(t).map(provider).orElseGet(supplier); } 23 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 24.
    You can “unit”test your performance @Test public void testPerf() throws Exception { Result result = benchmark(4, 1000, (thread, pass) -> singlePass(thread, pass)); LOG.info(Table.print(result)); assertExecTimes(result); } 24 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 25.
    Ugly? But it’sup to 10x faster… /** @return ofNullable(t).map(provider).orElseGet(supplier) */ public static <T, R> R optGet( T t, Function<T, R> provider, Supplier<R> supplier) { return t == null ? supplier.get() : optGet(provider.apply(t), supplier); } /** @return ofNullable(t).orElseGet(supplier) */ public static <T> T optGet(T t, Supplier<T> supplier) { return t == null ? supplier.get() : t; } 25 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 26.
    5 26 The task isdocumented and closed In case you just woke up… Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 27.
    Brace yourself Java WILLbe updated every 6 months. Make sure you’re armed and ready 27 Confidential/Restricted/Public Presentationorparttitle 13/11/2017
  • 28.