JAVA 9 SCHEDULE
•16th March 2017 Rampdown Phase 2
•6th July 2017 Final Release Candidate
•27th July 2017 General Availability
Slide 3
Slide 3 text
THINGS I CAN’T TALK ABOUT YET
Detailed performance metrics
Experience based analysis
Slide 4
Slide 4 text
http://openjdk.java.net/projects/jdk9/
Slide 5
Slide 5 text
AGENDA
• JEP-213: Milling project coin
• JEP-102: Process API updates
• JEP-266: More concurrency updates
• JEP-269: Convenience factory methods for collections
• JEP-277: Enhanced deprecation
• JEP-259: Stack-Walking API
Slide 6
Slide 6 text
AGENDA
• Date & Time API enhancements
• Stream/Optional API enhancements
• JShell
Slide 7
Slide 7 text
JSR 376: JAVA PLATFORM MODULE SYSTEM
Slide 8
Slide 8 text
• http://openjdk.java.net/projects/jigsaw/
• JEP 200: The Modular JDK
• JEP 220: Modular Run-Time Images
• JEP 260: Encapsulate Most Internal APIs
• JEP 261: Module System
• JEP 282: jlink: The Java Linker
JSR 376: JAVA PLATFORM MODULE SYSTEM
Slide 9
Slide 9 text
No content
Slide 10
Slide 10 text
No content
Slide 11
Slide 11 text
DIAMOND <> OPERATOR WITH
ANONYMOUS INNER CLASSES
Slide 12
Slide 12 text
DIAMOND <> OPERATOR WITH
ANONYMOUS INNER CLASSES
List strings = new ArrayList(){{
add("a"); add("b"); add("c");
}};
Java 8
Slide 13
Slide 13 text
DIAMOND <> OPERATOR WITH
ANONYMOUS INNER CLASSES
List strings = new ArrayList(){{
add("a"); add("b"); add("c");
}};
Java 8
List strings = new ArrayList<>(){{
add("a"); add("b"); add("c");
}};
Java 9
int _ = 1;
UNDERSCORE _ IS NOT ALLOWED
AS AN IDENTIFIER NAME
Slide 19
Slide 19 text
int _ = 1;
UNDERSCORE _ IS NOT ALLOWED
AS AN IDENTIFIER NAME
Java 8: warning: '_' used as an identifier
int _ = 1;
^
(use of '_' as an identifier might not be
supported in releases after Java SE 8)
Slide 20
Slide 20 text
int _ = 1;
UNDERSCORE _ IS NOT ALLOWED
AS AN IDENTIFIER NAME
Java 9: error: as of release 9, '_' is a keyword,
and may not be used as an identifier
int _ = 1;
^
Slide 21
Slide 21 text
public class UnderscoreDemo {
public static void main(String[] __) {
for (int ___ = 0; ___ < __.length; ___++)
System.out.println(__[___]);
}
}
UNDERSCORE _ IS NOT ALLOWED
AS AN IDENTIFIER NAME
Slide 22
Slide 22 text
UNDERSCORE _ IS NOT ALLOWED
AS AN IDENTIFIER NAME
JEP-302: Lambda leftovers (Java 10?)
BiFunction biss =
(i, _) -> String.valueOf(i);
Slide 23
Slide 23 text
UNDERSCORE _ IS NOT ALLOWED
AS AN IDENTIFIER NAME
JEP-302: Lambda leftovers (Java 10?)
BiFunction biss =
(i, _) -> String.valueOf(i);
Slide 24
Slide 24 text
PRIVATE METHODS IN INTERFACES
interface SomeInterface {
default void methodA() {}
private void methodB() {}
private static void methodC(){}
private default methodD(){}
}
// since Java 8
// new in Java 9
// new in Java 9
// error: cannot be
// private and default
Slide 25
Slide 25 text
@SAFEVARARGS ON PRIVATE METHODS
List list1 = singletonList("Hi");
List list2 = singletonList("Hi");
call(list1, list2);
static void call(List... lists) {
String s = lists[0].get(0);
System.out.println(s);
}
Slide 26
Slide 26 text
@SAFEVARARGS ON PRIVATE METHODS
List list1 = singletonList("Hi");
List list2 = singletonList("Hi");
call(list1, list2);
static void call(List... lists) {
String s = lists[0].get(0);
System.out.println(s);
}
warning: [unchecked] Possible heap pollution from parameterized vararg type
List: static void call(List... lists) {
warning: [unchecked] unchecked generic array creation for varargs parameter of
type List[]: call(myList1, myList2);
Slide 27
Slide 27 text
@SAFEVARARGS ON PRIVATE METHODS
List list1 = singletonList("Hi");
List list2 = singletonList("Hi");
call(list1, list2);
@SafeVarargs
static void call(List... lists) {
String s = lists[0].get(0);
System.out.println(s);
}
Slide 28
Slide 28 text
@SAFEVARARGS ON PRIVATE METHODS
List list1 = singletonList("Hi");
List list2 = singletonList("Hi");
call(list1, list2);
@SafeVarargs
private void call(List... lists) {
String s = lists[0].get(0);
System.out.println(s);
}
error: Invalid SafeVarargs annotation.
Instance method call(List...) is not final.
private void call(List... stringLists) {
^
Java 8:
Slide 29
Slide 29 text
@SAFEVARARGS ON PRIVATE METHODS
List list1 = singletonList("Hi");
List list2 = singletonList("Hi");
call(list1, list2);
@SafeVarargs
private void call(List... lists) {
String s = lists[0].get(0);
System.out.println(s);
}
Java 9: O.K.
Slide 30
Slide 30 text
CORE
THE
Slide 31
Slide 31 text
PROCESS API UPDATES
Slide 32
Slide 32 text
PROCESS API UPDATES
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
String name = runtimeMXBean.getName();
String pid = name.split("@")[0];
Java 8:
Slide 33
Slide 33 text
PROCESS API UPDATES
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
String name = runtimeMXBean.getName();
String pid = name.split("@")[0];
Java 8:
long pid = ProcessHandle.current().getPid();
Java 9:
Slide 34
Slide 34 text
PROCESS API UPDATES
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
String name = runtimeMXBean.getName();
String pid = name.split("@")[0];
Java 8:
long pid = ProcessHandle.current().getPid();
Java 9:
Stream handles = ProcessHandle.allProcesses();
Slide 35
Slide 35 text
https://github.com/zeroturnaround/zt-exec
ZT PROCESS EXECUTOR
new ProcessExecutor()
.command("java", "-version")
.redirectOutput(Slf4jStream.of("MyProcess").asInfo())
.execute();
https://github.com/zeroturnaround/zt-process-killer
ZT PROCESS KILLER
int pid = Integer.parseInt(
FileUtils.readFileToString(
new File("pidfile")));
PidProcess process = Processes.newPidProcess(pid);
ProcessUtil.destroyGracefullyOrForcefullyAndWait(process,
30, TimeUnit.SECONDS, 10, TimeUnit.SECONDS);
FACTORY METHODS FOR COLLECTIONS
Set set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
set = Collections.unmodifiableSet(set);
Slide 41
Slide 41 text
FACTORY METHODS FOR COLLECTIONS
Set set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
set = Collections.unmodifiableSet(set);
Set set = Collections.unmodifiableSet(
new HashSet<>(Arrays.asList("a", "b", "c")));
Slide 42
Slide 42 text
FACTORY METHODS FOR COLLECTIONS
Set set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
set = Collections.unmodifiableSet(set);
Set set = Collections.unmodifiableSet(
new HashSet<>(Arrays.asList("a", "b", "c")));
Set set = Collections.unmodifiableSet(
Stream.of("a", "b", "c").collect(toSet()));
Slide 43
Slide 43 text
FACTORY METHODS FOR COLLECTIONS
Set set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
set = Collections.unmodifiableSet(set);
Set set = Collections.unmodifiableSet(
new HashSet<>(Arrays.asList("a", "b", "c")));
Set set = Collections.unmodifiableSet(
Stream.of("a", "b", "c").collect(toSet()));
Set set = Set.of("a", "b", "c");
Slide 44
Slide 44 text
@Deprecated
Slide 45
Slide 45 text
@Deprecated(since="9", forRemoval=true)
Slide 46
Slide 46 text
@Deprecated(since="9", forRemoval=true)
Still no description or info
Slide 47
Slide 47 text
No content
Slide 48
Slide 48 text
No content
Slide 49
Slide 49 text
STACK-WALKING API
StackWalker VS Thread::getStackTrace
• Filter / asset / skip certain frames
• Get the instance of declaring class itself
• Get either a short stack trace or complete stack
trace
Slide 50
Slide 50 text
STACK-WALKING API
StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
List stack = walker.walk(
s -> s.collect(Collectors.toList())
);
Slide 51
Slide 51 text
STACK-WALKING API
StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
List stack = walker.walk(
s -> s.collect(Collectors.toList())
);
List stack = walker.walk(
s -> s.filter(f -> interestingClasses.contains(
f.getDeclaringClass())).findFirst()
);
Slide 52
Slide 52 text
DATE & TIME API IMPROVEMENTS
Slide 53
Slide 53 text
DATE & TIME API IMPROVEMENTS
LocalDate now = LocalDate.now(); // 2017-04-20
LocalDate java9release = LocalDate.of(2017, Month.JULY, 27);
now.datesUntil(java9release);
JDK-8146218 - Add LocalDate.datesUntil method producing Stream
Slide 54
Slide 54 text
DATE & TIME API IMPROVEMENTS
now.datesUntil(java9release, Period.ofDays(3));
LocalDate now = LocalDate.now(); // 2017-04-20
LocalDate java9release = LocalDate.of(2017, Month.JULY, 27);
now.datesUntil(java9release);
JDK-8146218 - Add LocalDate.datesUntil method producing Stream
Slide 55
Slide 55 text
DATE & TIME API IMPROVEMENTS
JDK-8146218 - Add LocalDate.datesUntil method producing Stream
LocalDate now = LocalDate.now(); // 2017-04-20
LocalDate java9release = LocalDate.of(2017, Month.JULY, 27);
now.datesUntil(java9release);
now.datesUntil(java9release, Period.ofDays(3))
.forEach(out::println);
Slide 56
Slide 56 text
DATE & TIME API IMPROVEMENTS
JDK-8146218 - Add LocalDate.datesUntil method producing Stream
LocalDate now = LocalDate.now(); // 2017-04-20
LocalDate java9release = LocalDate.of(2017, Month.JULY, 27);
now.datesUntil(java9release);
now.datesUntil(java9release, Period.ofDays(3))
.forEach(out::println);
2017-04-20
2017-04-23
2017-04-26
2017-05-29
…
Slide 57
Slide 57 text
DATE & TIME API IMPROVEMENTS
JDK-8142936 - Duration methods for days, hours, minutes, seconds, etc.
Duration#toDaysPart()
Duration#toHoursPart()
Duration#toMinutesPart()
Duration#toSecondsPart()
Duration#toMillisPart()
Duration#toNanosPart()
Slide 58
Slide 58 text
DATE & TIME API IMPROVEMENTS
JDK-8142936 - Duration methods for days, hours, minutes, seconds, etc.
Duration.ofMinutes(15000).toDaysPart(); // 10
Slide 59
Slide 59 text
DATE & TIME API IMPROVEMENTS
JDK-8142936 - Duration methods for days, hours, minutes, seconds, etc.
Duration.ofMinutes(15000).toDaysPart(); // 10
JDK-8148849 - Truncating Duration.
Duration.ofMinutes(15000).truncatedTo(ChronoUnit.DAYS); // 10
Slide 60
Slide 60 text
DATE & TIME API IMPROVEMENTS
JDK-8142936 - Duration methods for days, hours, minutes, seconds, etc.
Duration.ofMinutes(15000).toDaysPart(); // 10
JDK-8148849 - Truncating Duration.
Duration.ofMinutes(15000).truncatedTo(ChronoUnit.DAYS); // 10
JDK-8032510 - Add Duration.dividedBy(Duration)
Duration.ofDays(10).dividedBy(Duration.ofMinutes(1000)); // 14