-
Notifications
You must be signed in to change notification settings - Fork 0
/
extended.html
661 lines (598 loc) · 80.7 KB
/
extended.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="author" content="Benjamin Schmid @bentolor <[email protected]>"><title>Power Catch-up: Everything Practical and Important in Java 9 to 13</title><meta content="yes" name="apple-mobile-web-app-capable"><meta content="black-translucent" name="apple-mobile-web-app-status-bar-style"><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui" name="viewport"><link href="reveal.js/css/reveal.css" rel="stylesheet"><link rel="stylesheet" href="css/sky.css" id="theme"><!--This CSS is generated by the Asciidoctor-Reveal.js converter to further integrate AsciiDoc's existing semantic with Reveal.js--><style type="text/css">.reveal div.right {
float: right;
}
/* callouts */
.conum[data-value] {display:inline-block;color:#fff!important;background-color:rgba(50,150,50,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]:after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}</style><link rel="stylesheet" href="./fonts/fontawesome/css/all.css"><link href="css/atom-one-light.css" rel="stylesheet"><script>var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? "reveal.js/css/print/pdf.css" : "reveal.js/css/print/paper.css";
document.getElementsByTagName( 'head' )[0].appendChild( link );</script><!--[if lt IE 9]><script src="reveal.js/lib/js/html5shiv.js"></script><![endif]--><link rel="stylesheet" href="css/presentation.css"></head><body><div class="reveal"><div class="slides"><section class="title" data-state="title"><h1>Power Catch-up</h1><h2>Everything Practical and Important in Java 9 to 13</h2><div class="preamble"><aside class="notes"><div class="ulist"><ul><li><p>Zur Person: Technology Advisor bei der eXXcellent solutions: IT Dienstleister mit Standorten in Ulm, München, Stuttgart, Darmstadt, Berlin: Individuelle Softwarelösungen – vorrangig Java & Web; auch .NET/Mobile/SAP. Klassisch.</p></li><li><p>Bin seit 18+ Jahren führend & beratend im Projektgeschäft unterwegs.
Stets in der Rolle technische Innovationen den Projekte & Kollegen näher zu bringen.</p></li><li><p>Lange Jahre war das im Java-Umfeld eher entspannter. Innovationen eher im Umfeld Docker/Kubernetes und auf der JVM eher Kotlin wo ich ebenfalls großer Fan bin.</p></li><li><p>Hat sich aber kräfitg geändert. Auch bei Java hat in letzter Zeit mehr Forwärtsbewegung eingesetzt und es gilt als auch im Kernsprache selbst wieder mehr „am Ball“ zu bleiben.</p></li></ul></div></aside></div><p class="author"><small>Benjamin Schmid @bentolor <[email protected]></small></p> <p><small>Navigation help: <code>?</code></small></p></section>
<section><section id="_tldr" data-background-image="images/manuscript.jpg"><h2><span class="tldr"><code>tl;dr</code></span></h2><div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p>Photo by <a href="https://de.freeimages.com/photographer/bjearwicke-46112">Benjamin Earwicker</a></p></li><li><p>Another photo</p></li><li><p>lorem</p></li></ul></div></div></div><aside class="notes"><div class="ulist"><ul><li><p>Motivation: Too long – didn’t read – Eine komprimierte Zusammenfassung aller wichtigen Änderungen.</p></li><li><p>Challenge, denn</p><div class="ulist"><ul><li><p>High-level Überblick vs.</p></li><li><p>Viele wertvolle API-Details und damit Anschauungsmaterial / Codebeispiele</p></li></ul></div></li></ul></div></aside></section><section id="_what_happened" data-background-image="images/jdk-timeline.png" data-background-size="contain"><div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p>[Support Modell: <a href="https://craftsmen.nl/java-11-is-here-to-stay/" class="bare">https://craftsmen.nl/java-11-is-here-to-stay/</a>]</p></li></ul></div></div></div>
<aside class="notes"><div class="paragraph"><p>What happened? You all heard of it!</p></div>
<div class="ulist"><ul><li><p>New cadence – every 6 months new java major release</p></li><li><p>No support overlap → Support Cliff</p></li><li><p>Every 3 years a LTS; v11: 2018-09; next v17: 2021-09</p></li></ul></div></aside></section><section id="_everything_is_so_awful" class="decentlightbg" data-background-video="videos/fog-hands.mp4" data-background-video-loop data-background-opacity="0.6"><h2>» Everything-is-so-awful™ «</h2><div class="olist arabic"><ol class="arabic"><li><p><strong>Oracle Java 8 installations are dead!</strong><br>
<span class="verydecent x-small"><em>Unmaintained:</em> No $free & security- & bugfix updates.</span></p></li><li><p>Always <strong>only 1 supported</strong> Oracle Java</p></li><li><p><strong>Every 6 months</strong> new major version;<br>
predecessor <strong>expire the same day</strong><br></p></li><li><p>You must <strong>always pay in production</strong> for Oracle Java</p></li></ol></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="https://www.oracle.com/technetwork/java/java-se-support-roadmap.html">Oracle Java SE Support Roadmap</a></p></li><li><p><a href="https://access.redhat.com/articles/1299013">OpenJDK Life Cycle and Support Policy</a>,</p></li></ul></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>Im Change Management sagt man ja oft: Für Änderung braucht es <em>Urgency</em></p></li></ul></div>
<div class="paragraph"><p><strong>Nachdem das klar ist: Publikumsfrage zu Vermutungsbestätigung</strong></p></div>
<div class="ulist"><ul><li><p>Wer arbeitet schon mit aktuellen Java 12</p></li><li><p>Wer arbeitet vorrangig Java 8? → Wer mit Oracle JVM: könnte theoretisch Supportvertrag haben…</p></li><li><p>Wer traut sich, die Anderen zu ermutigen, dass Sie nicht Alleine sind mit Java Versionen 6 und älter?</p></li></ul></div>
<div class="paragraph"><p>Aus Projekten: Kenne ich die Prävalenz von Java 8 und älter.</p></div></aside></section><section id="_love_peace_happiness" class="lightbg" data-background-video="videos/flowers.mp4" data-background-video-loop data-background-opacity="0.6"><h2>Love, peace & happiness…</h2><div class="ulist"><div class="title">Starting with Java 11</div><ul><li><p>Oracle themselves releases OpenJDK<br>
<span class="decent x-small">(<span class="icon"><i class="fa fa-exclamation-triangle"></i></span> but only 6 month support cadence)</span></p></li><li><p>OpenJDK <em>defacto identical</em> to Oracle JDK</p></li><li><p>Numerous (new) OpenJDK-based options.<br>
<span class="decent x-small">Some with $free support</span></p></li></ul></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="https://blogs.oracle.com/java-platform-group/oracle-jdk-releases-for-java-11-and-later">Oracle Blog: Oracle JDK Releases for Java 11 and Later</a>,</p></li><li><p><a href="https://medium.com/@javachampions/java-is-still-free-2-0-0-6b9aa8d6d244">Java is Still Free 2.0.3</a></p></li></ul></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>Oracle veröffentlich selbst unter zwei Lizenzen: GPLv2+CPE und commercial licence</p></li><li><p>Providers are IBM, Amazon, Alibaba, Azul, SAP, many more – listed in references</p></li></ul></div></aside></section><section id="_openjdk_suppliers" class="lightbg degrade" data-background-video="videos/flowers.mp4" data-background-video-loop data-background-opacity="0.6"><h2>OpenJDK Suppliers</h2><div class="ulist"><ul><li><p><a href="https://adoptopenjdk.net/">AdoptOpenJDK</a> <span class="decent">(LTS: 4yr, 1yr overlap)</span></p></li><li><p><a href="https://access.redhat.com/articles/1299013">Red Hat (IBM)</a> <span class="decent">(v8: 2023 v11: 2024)</span></p></li><li><p><a href="https://aws.amazon.com/corretto/">Amazon Corretto</a>,
<a href="https://github.com/alibaba/dragonwell8">Alibaba</a>,
<a href="https://www.azul.com/products/zulu-enterprise/">Azul Zulu</a>,
<a href="https://github.com/SAP/SapMachine">SAP</a>,
<a href="https://www.ibm.com/marketplace/support-for-runtimes">IBM</a>,
<a href="https://bell-sw.com/java.html">BellSoft</a>,
<a href="https://www.jclarity.com/">jClarity</a>, Distributionen, …</p></li></ul></div></section><section id="_tldr_adoptopenjdk" class="degrade" data-transition="zoom-in convex-out" data-background-video="videos/flowers.mp4" data-background-video-loop data-background-opacity="0.6"><h2><code>tl;dr</code>: AdoptOpenJDK</h2><div class="paragraph"><p><span class="image"><img src="images/adopt-openjdk-entry.png" alt="AdoptOpenJDK" width="950"></span><br>
<span class="decent x-small">LTS Support for Java 8 (2023) & 11 (2022) & ff.</span></p></div>
<aside class="notes"><div class="ulist"><ul><li><p><code>tl;dr</code> – pick AdoptOpenJDK</p></li></ul></div></aside></section><section id="_adoptopenjdk_sponsors" class="degrade" data-transition="convex-in" data-background-video="videos/flowers.mp4" data-background-video-loop data-background-opacity="0.6"><h2>AdoptOpenJDK – Sponsors</h2><div class="imageblock" style=""><img src="images/adopt-openjdk-sponsors.png" alt="AdoptOpenJDK Sponsors"></div>
<aside class="notes"><div class="ulist"><ul><li><p>AdoptOpenJDK backed by Amazon, Azul, GoDaddy, IBM, jClarity, Pivotal, Red Hat, …</p></li></ul></div></aside></section><section id="_adoptopenjdk_plattforms" class="degrade" data-transition="convex-in convex-out" data-background-video="videos/flowers.mp4" data-background-video-loop data-background-opacity="0.6"><h2>AdoptOpenJDK – Plattforms</h2><div class="imageblock" style=""><img src="images/adopt-openjdk-plattforms.png" alt="AdoptOpenJDK Plattforms"></div>
<aside class="notes"><div class="ulist"><ul><li><p>New since Java 9: ARM & s/390 – so if you have a mainframe in the basement… or an raspberry pi… You know what to do!</p></li></ul></div></aside></section><section id="_adoptopenjdk_support_timelines" class="bonuscontent degrade" data-transition="convex-in convex-out" data-background-video="videos/flowers.mp4" data-background-video-loop data-background-opacity="0.6"><h2>AdoptOpenJDK – Support Timelines</h2><div class="imageblock" style=""><img src="images/adopt-openjdk-support.png" alt="AdoptOpenJDK Support Table"></div>
<aside class="notes"><div class="ulist"><ul><li><p>OpenJDK 8 supported: 2023, OpenJDK 11: 2025</p></li></ul></div></aside></section></section>
<section id="_agenda" class="lightbg" data-background-video="videos/relaxing.mp4" data-background-video-loop data-background-opacity="0.7"><h2>Agenda</h2><div class="olist arabic"><ol class="arabic"><li><p>Java 9—​13 Overview</p></li><li><p>Language</p></li><li><p>API</p></li><li><p>Tooling</p></li><li><p>Java 14 & beyond</p></li></ol></div>
<div class="paragraph"><p> <br>
<span class="decent"><span class="icon"><i class="fa fa-hand-point-right"></i></span> v12+ & Preview Features:</span> <span class="version">12</span> <span class="version">13</span> <span class="preview">preview</span></p></div>
<aside class="notes"><div class="paragraph"><p>While you lean back and take a beer, I’ll …</p></div>
<div class="ulist"><ul><li><p>Note: I’ll emphasize features newer than 11</p></li></ul></div></aside></section>
<section><section id="_java_913_in_a_nutshell" class="lightbg" data-background-video="videos/coffee-beans.mp4" data-background-video-loop data-background-opacity="0.7"><h2>Java 9—​13 in a nutshell</h2></section><section id="_v9_huge"><h2>v9 (huge…)</h2><div class="ulist"><ul><li><p><strong>Java module (Jigsaw)</strong></p></li><li><p><strong>API Improvements:</strong> <em>Project Coin Milling</em>, Stream, …</p></li><li><p><strong>Unified JVM & Java Logging</strong>, …</p></li><li><p><strong>Performance</strong></p></li><li><p><em>Tools:</em> <code>jshell</code> <code>jlink</code> <code>-release</code>, Multi-Release JARs</p></li></ul></div>
<div class="paragraph"><p><span class="decent">2017-03-23, <span class="icon"><i class="fa fa-exclamation-circle"></i></span> <a href="http://openjdk.java.net/projects/jdk9/"><strong>91</strong> JEPs</a></span></p></div>
<aside class="notes"><div class="paragraph"><p>The <strong>biggest</strong> release of all.</p></div>
<div class="ulist"><ul><li><p>Mostly modular JRE & accompagning tools</p></li><li><p>Many helpful API enhancements</p></li><li><p>…and <strong>Performance</strong> enhancements!</p></li></ul></div></aside></section><section id="_v10"><h2>v10</h2><div class="ulist"><ul><li><p><code>var</code>: <strong>Local-Variable Type Inference</strong></p></li><li><p><strong>Performance</strong>: GC, Class-Data Sharing, Threads, …</p></li><li><p><em>Experimental:</em> <strong>Graal AoT-Compiler</strong></p></li></ul></div>
<div class="paragraph"><p><span class="decent">2018-03-20, <a href="http://openjdk.java.net/projects/jdk/10/">12 JEPs</a></span></p></div>
<aside class="notes"><div class="ulist"><ul><li><p><code>var</code>: really noteable feature</p></li><li><p>…and <strong>Performance!</strong></p></li></ul></div></aside></section><section id="_v11_lts"><h2>v11 [LTS]</h2><div class="ulist"><ul><li><p>New <strong>HTTP/2- & Websocket</strong>-Client</p></li><li><p><strong>New GCs</strong>: Low-latency ZGC, No-op Epsiolon GC</p></li><li><p><strong>Ex-payware:</strong> <strong>Flight Recorder</strong>, ZGC, CDS, …<br>
→ Oracle JDK ≌ OpenJDK</p></li><li><p><strong>Dropped:</strong> Java EE, JavaFX, CORBA</p></li><li><p>HTML5 Javadoc, <strong>Unicode 10</strong>, …</p></li><li><p><strong>Updated Crypto</strong>: TLS 1.3, new Kex & Ciphers</p></li></ul></div>
<div class="paragraph"><p><span class="decent">2018-09-25, <a href="http://openjdk.java.net/projects/jdk/11/">17 JEPs</a></span></p></div>
<aside class="notes"><div class="ulist"><div class="title">Polishing & Cleanup release</div><ul><li><p>Many cleanups like dropping EE, JavaFX, CORBA</p></li><li><p>Payware → FOSS</p></li><li><p>New GCs which improve… <strong>Performance</strong></p></li></ul></div></aside></section><section id="_v12"><h2>v12</h2><div class="ulist"><ul><li><p><strong>Low-pause GC</strong> „Shenandoah“</p></li><li><p><strong>Microbenchmark Suite</strong></p></li><li><p><em>Preview:</em> Switch Expressions</p></li><li><p><strong>Performance</strong> improvements<br>
<span class="verydecent">(CDS, G1 GC, Constants)</span></p></li></ul></div>
<div class="paragraph"><p><span class="decent">2019-03-19, <a href="http://openjdk.java.net/projects/jdk/12/">8 JEPs</a></span></p></div>
<aside class="notes"><div class="ulist"><ul><li><p>Switch Preview … stays Preview in 13</p></li><li><p>Again: <strong>Performance, Performance, Performance…</strong></p></li></ul></div></aside></section><section id="_v13"><h2>v13</h2><div class="ulist"><ul><li><p><em>Updated Preview:</em> <strong>Switch-Expression</strong></p></li><li><p><em>Preview:</em> <strong>Text Blocks</strong></p></li><li><p><strong>Performance</strong> improvements<br>
<span class="verydecent">(AppCDS, ZGC, Socket)</span></p></li></ul></div>
<div class="paragraph"><p><span class="icon"><i class="fa fa-calendar-alt"></i></span> <span class="decent">2019-09-17, <a href="http://openjdk.java.net/projects/jdk/12/">5 JEPs</a></span></p></div>
<aside class="notes"><div class="ulist"><ul><li><p>Even more playstuff! Adding Text blocks</p></li><li><p>Again: Performance!</p></li></ul></div></aside></section></section>
<section><section id="_language" class="lightbg" data-background-video="videos/woman-study.mp4" data-background-video-loop data-background-opacity="0.7"><h2>Language</h2></section><section id="_local_variable_type_inference_jep_286"><h2>Local Variable Type Inference <span class="jep"><a href="https://openjdk.java.net/jeps/286">JEP 286</a></span></h2><div class="openblock col2"><div class="content"><div class="ulist"><ul><li><p>New reserved Java type <code>var</code></p></li><li><p><em>„real type“</em> inferred by compiler <strong>on first initialization</strong></p></li><li><p>can denote classes (<code>Integer</code>) & primitives (<code>int</code>)</p></li><li><p><strong>only</strong> available for <em>local variables</em></p></li></ul></div></div></div>
<pre class="highlight listingblock source col2"><code data-noescape class="java language-java">var primitiveVal = 5; // int
var doubleVal = 5d; // double
final var sl = new ArrayList<String>();
var letters = "";
for (var s : sl) {
letters += s.toLowerCase();
}
// var: enable annotation w/ type infer
(var x, @NotNull var y) -> x + y;</code></pre>
<aside class="notes"><div class="ulist"><ul><li><p>Especially helpful for Generic Type madness <code>List<? extends Foo<? extends Number>></code>…</p></li><li><p><strong>first initialization</strong> → Type!</p></li><li><p>only vars</p></li></ul></div>
<div class="paragraph"><p>Really a beauty</p></div></aside></section><section id="_type_inferencebordercases" class="degrade"><h2>Type Inference — Bordercases</h2><pre class="highlight listingblock"><code data-noescape class="java language-java">// var wontCompile; <i class="conum" data-value="1"></i><b>(1)</b>
// var wontCompile = null;
// var wontCompile = {-1, 1};
var myMap = new HashMap<>();
myMap.put(42, "The answer");
// var wontCompile = myMap.get(42).trim(); <i class="conum" data-value="2"></i><b>(2)</b>
// var wontCompile = String::toUpperCase; <i class="conum" data-value="3"></i><b>(3)</b>
var myPredicate = new IntPredicate() {
public boolean test(int value) { return value > 0; } };
// myPredicate = (int i) -> (i % 2) == 0; <i class="conum" data-value="4"></i><b>(4)</b></code></pre>
<div class="colist arabic"><table><tr><td><i class="conum" data-value="1"></i><b>1</b></td><td>Type <em>must be inferrable</em> – no late init, <code>null</code> or array literals</td></tr><tr><td><i class="conum" data-value="2"></i><b>2</b></td><td>Type <em>inferred at declaration</em> time: <code>Map<Object, Object></code></td></tr><tr><td><i class="conum" data-value="3"></i><b>3</b></td><td><em>Method references</em> must be explicit</td></tr><tr><td><i class="conum" data-value="4"></i><b>4</b></td><td><em>Anonymous Types</em> are types-per-instance; therefore no reassignment</td></tr></table></div>
<aside class="notes"><div class="ulist"><ul><li><p>Type <em>must be inferrable</em> – no late init, <code>null</code> or array literals</p></li><li><p>Type <em>inferred at declaration</em> time: <code>Map<Object, Object></code></p></li><li><p><em>Method references</em> must be explicit</p></li><li><p><em>Anonymous Types</em> are types-per-instance; therefore no reassignment</p></li></ul></div></aside></section><section id="_lambda_type_inference_jep_323" class="bonuscontent"><h2>Lambda Type inference <span class="jep"><a href="https://openjdk.java.net/jeps/323">JEP 323</a></span></h2><pre class="highlight listingblock"><code data-noescape class="java language-java">// JDK8
MyLambda myLambda = (x, y) -> x + ((y != null) ? y : 0);
myLambda = (Long x, @NotNull Long y) -> x + y;
// JDK11: `var` style → type infer with annotations
myLambda = (var x, @NotNull var y) -> x + y;</code></pre></section><section id="_type_inference_styleguide"><h2>Type inference: Styleguide</h2><div class="videoblock stretch"><video src="videos/type-infer-styleguide.mp4" width="100%" height="100%" poster="images/Style%20Guidelines%20for%20Local%20Variable%20Type%20Inference%20in%20Java" controls>Your browser does not support the video tag.</video></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="http://openjdk.java.net/projects/amber/LVTIstyle.html">Style Guidelines for Local Variable Type Inference in Java</a></p></li></ul></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>May hide things: Project wrote a styleguide with recommendations</p></li><li><p>Don’t make source-code reading a puzzle</p></li></ul></div></aside></section><section id="_milling_project_coin_jep_213"><h2>Milling Project Coin <span class="jep"><a href="https://openjdk.java.net/jeps/213">JEP 213</a></span></h2><div class="title">Try-with-resources now support „effectively final“ variables</div><pre class="highlight listingblock"><code data-noescape class="java language-java">var inputStream = new FileInputStream(".gitignore");
try (inputStream) { … }</code></pre>
<div class="openblock tgap fragment"><div class="content"><div class="title">Private methods in Interfaces</div><pre class="highlight listingblock"><code data-noescape class="java language-java">interface Version {
byte[] digits();
default String text() { return text(digits()); }
private String text(byte[] version) { … }
}</code></pre>
<div class="paragraph"><p><span class="verydecent">Allows default methods share common code</span></p></div></div></div>
<aside class="notes"><div class="paragraph"><p>Milling Project Coin: A long runner project. Continously delivering small enhancement changes to Java</p></div></aside></section><section id="_milling_project_coin" class="bonuscontent"><div class="title">Diamond operator for anonymous inner classes</div><pre class="highlight listingblock"><code data-noescape class="java language-java">Comparator<Integer> compareLongs = new Comparator<>() { … }</code></pre>
<div class="openblock tgap fragment"><div class="content"><div class="title"><code>@SafeVargs</code> on private instance methods</div><pre class="highlight listingblock"><code data-noescape class="java language-java">private List<String> safeVarargsMethod(List<String>... lists) { … }</code></pre></div></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p>(1) <a href="https://www.javaworld.com/article/3169388/java-9s-other-new-enhancements-part-2.html">Java 9’s other new enhancements, Part 2: Milling Project Coin</a></p></li></ul></div></div></div></section><section id="_preview_features_preview_12"><h2>Preview features <span class="preview">Preview</span> <span class="version">12</span></h2><div class="openblock col2"><div class="content"><div class="title">Unlock Compilation</div><pre class="highlight listingblock"><code data-noescape class="bash language-bash">javac --release xx --enable-preview</code></pre></div></div>
<div class="openblock col2"><div class="content"><div class="title">Unlock Execution</div><pre class="highlight listingblock"><code data-noescape class="bash language-bash">java --enable-preview …</code></pre></div></div>
<div class="openblock clear"><div class="content"><div class="paragraph"><p> <br>
<span class="decent"><code>xx</code> must <em>exactly</em> match used JDK version</span></p></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>New in Java 12</p></li><li><p>Allow to preview/use features.</p></li><li><p>Forces awareness by using toggle switch on <em>compiling and running</em></p></li></ul></div></aside></section><section id="_switch_in_java_8" data-transition="fade-out"><h2><code>switch</code> in Java 8</h2><pre class="highlight listingblock"><code data-noescape class="java language-java"> enum Direction {N, S, W, E}
String switchExpressionJDK8(Direction way) {
String result;
switch (way) {
case N:
result = "Up";
break;
case S:
result = "Down";
break;
case E:
case W:
result = "Somewhere left or right";
break;
default:
throw new IllegalStateException("Huh?: " + way);
}
return result;
}</code></pre>
<aside class="notes"><div class="ulist"><ul><li><p>Error-prone</p><div class="ulist"><ul><li><p>forget <code>break</code></p></li><li><p>must have a <code>default</code></p></li></ul></div></li><li><p>Clumsy: Temporary assign a variable</p></li></ul></div></aside></section><section id="_switch_expression_jep_325_12_jep_354_13_preview" data-transition="fade-in"><h2>Switch-Expression <span class="jep"><a href="https://openjdk.java.net/jeps/325">JEP 325</a></span> <span class="version">12</span> <span class="jep"><a href="https://openjdk.java.net/jeps/354">JEP 354</a></span> <span class="version">13</span> <span class="preview">Preview</span></h2><pre class="highlight listingblock"><code data-noescape class="java language-java">String switchExpressionPreview13(Direction way) {
return switch (way) { <i class="conum" data-value="1"></i><b>(1)</b>
case N -> "Up"; <i class="conum" data-value="2"></i><b>(2)</b>
case S -> { yield "Down"; } <i class="conum" data-value="3"></i><b>(3)</b>
case E, W -> "Somewhere left or right";
// default -> "Foo" <i class="conum" data-value="4"></i><b>(4)</b>
};
}</code></pre>
<div class="colist arabic"><table><tr><td><i class="conum" data-value="1"></i><b>1</b></td><td><code>switch</code> can be used as expression</td></tr><tr><td><i class="conum" data-value="2"></i><b>2</b></td><td><code>→</code> instead of <code>:</code> → no <code>break;</code> necessary!</td></tr><tr><td><i class="conum" data-value="3"></i><b>3</b></td><td>Lambdas can be used to. For <em>expressions</em> they must <code>yield</code> a value <span class="version">13</span></td></tr><tr><td><i class="conum" data-value="4"></i><b>4</b></td><td><code>default</code> can be ommitted if a) no expression or b) <code>enum</code> with every value handled</td></tr></table></div>
<aside class="notes"><div class="ulist"><ul><li><p>Preview kommt durchaus zum Einsatz: Switch-Expression wurde mit Java 12 eingeführt und in Java 13 verändert.</p></li><li><p><code>switch</code> can be used as expression</p></li><li><p><code>→</code> instead of <code>:</code> → no <code>break;</code> necessary!</p></li><li><p>Lambdas can be used to. For <em>expressions</em> they must <code>yield</code> a value <span class="version">13</span>
+ <code>default</code> can be ommitted if a) no expression or b) <code>enum</code> with every value handled</p></li></ul></div></aside></section><section id="_text_blocks_jep_355_13_preview"><h2>Text Blocks <span class="jep"><a href="https://openjdk.java.net/jeps/355">JEP 355</a></span> <span class="version">13</span> <span class="preview">Preview</span></h2><div class="openblock col2"><div class="content"><div class="title">Java 8</div><pre class="highlight listingblock"><code data-noescape class="java language-java">Object obj = engine.eval(
"function hello() {\n" +
" print(\"Hi, world!\");\n" +
"}\n" +
"\n" +
"hello();\n"
);</code></pre></div></div>
<div class="openblock col2"><div class="content"><div class="title">Java 13</div><pre class="highlight listingblock"><code data-noescape class="java language-java">Object obj = engine.eval("""
function hello() {
print("Hi, world!");
}
hello();
""");</code></pre></div></div>
<div class="openblock small decent"><div class="content"><div class="ulist"><ul><li><p>Leading space-Character identation removed<br>
up to the most-left character in the block including the closing <code>"""</code></p></li><li><p>Normalizes line-endings to <code>\n</code> and removes all trailing white spaces</p></li></ul></div></div></div>
<aside class="notes"></aside></section><section id="_jigsaw_jep_201"><h2>Jigsaw <span class="jep"><a href="https://openjdk.java.net/jeps/201">JEP 201</a></span></h2><div class="quoteblock"><blockquote><div class="paragraph"><p>Modules bundle together one or more packages
and offer stronger encapsulation than jars</p></div></blockquote></div>
<div class="ulist"><ul><li><p>Allows <strong>scaled-down runtime</strong> → IoT & Container</p></li><li><p><strong>Stronger:</strong> <code>public</code> invisible to other modules</p></li><li><p><em>Sad:</em> No module versioning</p></li></ul></div>
<aside class="notes"><div class="ulist"><ul><li><p>Only briefly: Most of you will know</p></li><li><p><strong>1 package = 1 module</strong></p></li></ul></div></aside></section><section id="_jigsaw" data-transition="fade-out"><div class="title">Metadata: <code>/module-info.java</code>:</div><pre class="highlight listingblock"><code data-noescape class="java language-java">module com.mysql.jdbc {
requires java.sql; // Module dependency
exports com.mysql.jdbc; // Export module package → enables access
provides java.sql.Driver // SPI: Provide service instance
with com.mysql.jdbc.Driver;
}</code></pre>
<div class="openblock tgap fragment"><div class="content"><div class="title">Jigsaw uses modules & <code>.jmod</code> instead of Classpath & <code>.jar</code></div><pre class="highlight listingblock"><code data-noescape>javac -mp modulepath ...
java -mp modulepath -m modulename/moduleclass</code></pre></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>Metadata described in <code>module-info.java</code></p></li><li><p><strong>Either-Or!</strong> You stay in classpath/JAR mode oder switch to modules /jmod</p></li></ul></div></aside></section><section id="_serviceloader_modules"><h2><code>ServiceLoader</code> & modules</h2><pre class="highlight listingblock"><code data-noescape class="java language-java">public abstract class BillingService {
public static BillingService getInstance() {
return ServiceLoader.load(BillingService.class)
.findFirst().orElseThrow();
}
public abstract String takeMyMoney();
}</code></pre>
<pre class="highlight listingblock"><code data-noescape class="java language-java">public class MastercardBillingService extends BillingService { … }</code></pre>
<pre class="highlight listingblock"><code data-noescape class="java language-java">module anothermodule {
provides bentolor.BillingService
with bentolor.MastercardBillingService;
}</code></pre>
<div class="paragraph"><p>→ Simply use via <code>BillingService.getInstance()</code></p></div></section><section id="_jigsaw_conclusion" data-transition="fade-in"><div class="quoteblock"><blockquote>It is too early to say whether modules will achieve widespread
use outside of the JDK itself. In the meantime, it seems best to
avoid them unless you have a compelling need.</blockquote><div class="attribution"><cite>Effective Java: Third Edition (2018)</cite><br>— Joshua Bloch</div></div></section></section>
<section><section id="_api" class="lightbg" data-background-video="videos/keyboard.mp4" data-background-video-loop data-background-opacity="0.7"><h2>API</h2></section><section id="_immutable_collection_factories_jep_269"><h2>Immutable Collection Factories <span class="jep"><a href="https://openjdk.java.net/jeps/269">JEP 269</a></span></h2><div class="title"><code>List/Set/Map.of()</code></div><pre class="highlight listingblock"><code data-noescape class="java language-java">/* Comment sections would break ... */
List<Integer> listOfNumbers = List.of(1, 2, 3, 4, 5/*, null*/);
Set<Integer> setOfNumbers = Set.of(1, 2, 3, 4, 5/*, 1*/);
Map<String, String> mapOfString = Map.of("key1", "value1", "key2", "value2");
Map<String, String> moreMaps = Map.ofEntries(
Map.entry("key1", "value1"),
Map.entry("key2", "value2")/*,
Map.entry("key1", "value3")*/
);</code></pre>
<div class="openblock decent"><div class="content"><div class="paragraph"><p>Produces <em>immutable</em> collections. All methods <em>fail on <code>null</code> values.</em> <br>
<code>Set.of()</code> and <code>Map.of()</code> break on <em>duplicate</em> (key) entries.</p></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>Long overdue. Sth. I always did on my own in nearly every project.</p></li></ul></div></aside></section><section id="_immutable_collection_copy"><h2>Immutable collection copy</h2><div class="title"><code>List/Set/Map.copyOf()</code></div><pre class="highlight listingblock"><code data-noescape class="java language-java">var listCopy = List.copyOf(originalList); // independent, immutable copy
var setCopy = Set.copyOf(originalList); // copy to other types
var mapCopy = Map.copyOf( … );
assert 3 == listCopy.size(); // ["a", "b", "a"]
assert 2 == setCopy.size(); // ["a", "b"]
// listCopy.add("z") // → UnsupportedOperationException</code></pre>
<div class="openblock tgap small"><div class="content"><div class="paragraph"><p><span class="decent"><em>Real copies</em> – independent from source vs. <code>Collections.unmodifiable()</code></span></p></div></div></div></section><section id="_files_io"><h2>Files & I/O</h2><pre class="highlight listingblock"><code data-noescape class="java language-java">var txtPath = Path.of("src", "test", "resources", "sample.txt"); <i class="conum" data-value="1"></i><b>(1)</b>
Path newPath = Path.of("src/test/resources/newfile.txt");
String fileContent = Files.readString(txtPath); <i class="conum" data-value="2"></i><b>(2)</b>
// → "Nostrum iure ullam."
Files.writeString(newPath, "Nostrum lore.", StandardOpenOption.CREATE); <i class="conum" data-value="3"></i><b>(3)</b>
long firstMismatch = Files.mismatch(txtPath, newPath); // → 8 | JDK12 <i class="conum" data-value="4"></i><b>(4)</b></code></pre>
<div class="colist arabic"><table><tr><td><i class="conum" data-value="1"></i><b>1</b></td><td>Directly create <code>Path</code>-instances</td></tr><tr><td><i class="conum" data-value="2"></i><b>2</b></td><td>Hassle-free reading a file content into a string</td></tr><tr><td><i class="conum" data-value="3"></i><b>3</b></td><td>…or writing into files</td></tr><tr><td><i class="conum" data-value="4"></i><b>4</b></td><td>Find position of first mismatching bytes of two Files <span class="version">12</span></td></tr></table></div>
<aside class="notes"><div class="ulist"><ul><li><p>Hassle-free reading a file content into a string or writing into files</p></li><li><p>Find position of first mismatching bytes of two Files <span class="version">12</span></p></li></ul></div></aside></section><section id="_stream_enhancements"><h2>Stream Enhancements</h2><div class="olist arabic"><ol class="arabic"><li><p><strong>Transform</strong> with <code>dropWhile()</code> & <code>takeWhile()</code></p></li><li><p><strong>Generate</strong> with <code>iterate()</code> & <code>ofNullable()</code>)</p></li><li><p><strong>Redirect</strong> with <code>transferTo()</code></p></li><li><p>Collect <strong>to immutables</strong> with <code>toUnmodifiableList()</code>,</p></li><li><p>… or <strong>invert</strong> filters with <code>Predicate.not()</code></p></li></ol></div></section><section id="_transform_generate_streams"><h2>Transform & Generate Streams</h2><div class="openblock fragment"><div class="content"><div class="title">Modify with <code>dropWhile()</code> & <code>takeWhile()</code></div><pre class="highlight listingblock"><code data-noescape class="java language-java">var stream = Stream.of(-1, 0, 1, 21, 42);
stream.dropWhile(i -> i < 2) // → [ 21, 42 ]
stream.takeWhile(i -> i < 2) // → [ -1, 0, 1 ]</code></pre></div></div>
<div class="openblock fragment"><div class="content"><div class="title">Redirect with <code>transferTo()</code></div><pre class="highlight listingblock"><code data-noescape class="java language-java">new ByteArrayInputStream(buf)
.transferTo(System.out); // InputStream → OutputStream</code></pre></div></div>
<div class="openblock fragment"><div class="content"><div class="title">Generate with <code>iterate()</code> & <code>ofNullable()</code></div><pre class="highlight listingblock"><code data-noescape class="java language-java">// Stream<T> iterate(seedValue, nextTest, applyFunc)
Stream.iterate(2, i -> i < 999, i -> i*i); // → [2, 4, 16, 256]
Stream.ofNullable(null); // [ ]
Stream.ofNullable("Hi"); // [ "Hi" ]</code></pre></div></div>
<aside class="notes"><div class="olist arabic"><ol class="arabic"><li><p>Werte anhand eines Filters überspringen oder begrenzen</p></li><li><p>Streams umleiten</p></li><li><p>Iterate-Stream oder Stream mit 0 oder 1 Element</p></li></ol></div></aside></section><section id="_collectors" class="left"><h2>Collectors</h2><div class="title">Dispatch a stream to two consuming Collectors with <code>teeing()</code></div><pre class="highlight listingblock"><code data-noescape class="java language-java">double rms(Stream<Integer> numStream) {
return rms = numStream.collect(
Collectors.teeing(
Collectors.summingDouble(i -> i * i), // → sum
Collectors.counting(), // → n
(sum, n) -> Math.sqrt(sum / n) // Join into final result
)
);
}</code></pre>
<div class="openblock tgap fragment small"><div class="content"><div class="ulist"><div class="title">More new <code>Collectors</code> goodness…</div><ul><li><p>Create immutable Stream copies with <code>toUnmodifiableList/set/Map()</code></p></li><li><p>unpack nested values using <code>flatMap()</code></p></li><li><p>filter out unwanted values using <code>filtering()</code></p></li></ul></div></div></div></section><section id="_predicatenot"><div class="title"><code>Predicate::not</code></div><pre class="highlight listingblock"><code data-noescape class="java language-java">stream.filter(s -> !s.isEmpty)</code></pre>
<div class="openblock fragment"><div class="content"><div class="title"><span class="icon"><i class="fa fa-angle-double-down"></i></span></div><pre class="highlight listingblock"><code data-noescape class="java language-java">stream.filter(Predicate.not(String::isEmpty))</code></pre></div></div>
<div class="openblock fragment"><div class="content"><div class="title"><span class="icon"><i class="fa fa-angle-double-down"></i></span></div><pre class="highlight listingblock"><code data-noescape class="java language-java">stream.filter(not(String::isEmpty))</code></pre></div></div></section><section id="_enhanced_optional"><h2>Enhanced <code>Optional</code></h2><div class="title">New <code>ifPresentOrElse()</code>, <code>or()</code>, <code>stream()</code> and <code>isPresent()</code></div><pre class="highlight listingblock"><code data-noescape class="java language-java">var maybeInt = Optional.ofNullable( (Math.random()<0.5) ? 42 : null );
maybeInt.ifPresentOrElse( // … do either this or that
(n) -> System.out.println(n),
() -> System.out.println("Nada") );</code></pre>
<pre class="highlight listingblock source fragment"><code data-noescape class="java language-java">// Optional empty? → Build a new one on-the-fly…
var triedAgain = maybeInt.or( () -> Optional.of(-1) );</code></pre>
<pre class="highlight listingblock source fragment"><code data-noescape class="java language-java">// Provide a stream → [] or [42]
Stream<Integer> intStream = maybeInt.stream();</code></pre>
<pre class="highlight listingblock source fragment"><code data-noescape class="java language-java">// Yay! – complements isPresent()
assert maybeInt.isPresent() == !maybeInt.isEmpty();</code></pre></section><section id="_new_processhandle_and_processbuilder"><h2>New <code>ProcessHandle</code> and <code>ProcessBuilder</code></h2><pre class="highlight listingblock"><code data-noescape class="java language-java">Process sleeper = new ProcessBuilder("sleep", "10s").start();
ProcessHandle sleepHandle = sleeper.toHandle();
// Perform Runnables on process exit
sleepHandle.onExit().thenRun( // → CompletableFuture
() -> out.println("`sleep` process exited") );
out.println(sleepHandle.info());
// → [user: ben, cmd: /bin/sleep, args: [10s], startTime:…, totalTime: …]
// Find …
ProcessHandle jvm = ProcessHandle.current(); // … JVM,
Stream<ProcessHandle> all = ProcessHandle.allProcesses(); // … all processes
jvm.children().forEach(out::println); // … or childs
// Kill …
sleepHandle.destroy();</code></pre>
<aside class="notes"><div class="ulist"><ul><li><p>much more convenient</p></li><li><p>provides <strong>more info</strong> and <strong>more control</strong></p></li><li><p>aid the creation of process pipelines</p></li></ul></div></aside></section><section id="_enhanced_deprecation_policy" class="left"><h2>Enhanced Deprecation policy</h2><div class="title"><code>@Deprecated</code> now wears a <code>forRemoval</code> flag</div><pre class="highlight listingblock"><code data-noescape class="java language-java">@Deprecated(since="1.2", forRemoval=true)
public final synchronized void stop(Throwable obj) {
throw new UnsupportedOperationException();
}</code></pre>
<div class="openblock tgap fragment"><div class="content"><div class="title"><code>jdeprscan</code>: Scan Jars for deprecated usages</div><pre class="highlight listingblock x-small"><code data-noescape>$ jdeprscan commons-math3-3.6.1.jar
Jar file commons-math3-3.6.1.jar:
class org/apache/commons/math3/fraction/BigFraction uses deprecated method java/math/BigDecimal::divide(Ljava/math/BigDecimal;II)…;
class org/apache/commons/math3/util/MathUtils uses deprecated method java/lang/Double::<init>(D)V
class org/apache/commons/math3/util/Precision uses deprecated method java/math/BigDecimal::setScale(II)Ljava/math/BigDecimal;</code></pre>
<div class="paragraph"><p><span class="verydecent">can filter for deprecated methods marked for removal</span></p></div></div></div></section><section id="_stackwalker" class="bonuscontent"><h2>StackWalker</h2><pre class="highlight listingblock"><code data-noescape class="java language-java">StackWalker.getInstance().walk(s ->
s.map( frame -> frame.getClassName()+ '/' +frame.getMethodName() )
.filter(name -> name.startsWith("de.bentolor"))
.limit(10)
.collect(Collectors.toList())
).forEach(out::println);</code></pre></section><section id="_http2_client_jep_110_jep_321"><h2>HTTP/2 Client <span class="jep"><a href="https://openjdk.java.net/jeps/110">JEP 110</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/321">JEP 321</a></span></h2><pre class="highlight listingblock"><code data-noescape class="java language-java">HttpClient client = HttpClient.newBuilder() <i class="conum" data-value="1"></i><b>(1)</b>
.version(HttpClient.Version.HTTP_2) <i class="conum" data-value="2"></i><b>(2)</b>
.connectTimeout(Duration.ofSeconds(3)).build();
URI uri = URI.create("https://www.exxcellent.de/");
HttpRequest req = HttpRequest.newBuilder(uri)
.header("Useragent", "MyDemo").GET().build();
var future = client.sendAsync(req, HttpResponse.BodyHandlers.ofString()) <i class="conum" data-value="3"></i><b>(3)</b>
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
var expensiveOperation = Math.pow(12345, 9876); // meanwhile do sth. else…
future.get(); // wait for completion of the background request</code></pre>
<div class="colist arabic"><table><tr><td><i class="conum" data-value="1"></i><b>1</b></td><td><strong>Fluent API</strong> and <strong>Builder Pattern</strong></td></tr><tr><td><i class="conum" data-value="2"></i><b>2</b></td><td><strong>Standardized HTTP client</strong> capable of <strong>HTTP/2</strong> and <strong>WebSocket</strong> connections!</td></tr><tr><td><i class="conum" data-value="3"></i><b>3</b></td><td>Start <strong>asynchronously</strong> HTTP requests in the background</td></tr></table></div>
<aside class="notes"><div class="ulist"><ul><li><p>Standardized HTTP client capable of WebSocket connections!</p><div class="ulist"><ul><li><p>Java 8 UrlConnection too abstract</p></li><li><p>New client: Fluent API</p></li></ul></div></li><li><p>Support for asynchronous requests!</p></li><li><p>Support for Proxying, Cookies, Authentication</p></li></ul></div></aside></section><section id="_websocket_client"><h2>WebSocket client</h2><pre class="highlight listingblock"><code data-noescape class="java language-java">var wsBuilder = HttpClient.newHttpClient().newWebSocketBuilder();
var wsFuture = wsBuilder.buildAsync(URI.create("wss://echo.websocket.org"),
new WebSocket.Listener() {
onOpen(webSocket) { … }
onText(webSocket, data, last) { … }
onBinary(webSocket, data,last) { … }
onPing(webSocket, message) { … }
onPong(webSocket, message) { … }
onClose(webSocket, statusCode, reason) { … }
onError(webSocket, error) { … }
});
WebSocket websocket = wsFuture.join();
websocket.sendText("Ping!", true);
websocket.sendClose(NORMAL_CLOSURE, "Goodbye!").join();</code></pre></section><section id="_reactive_streams"><h2>Reactive Streams</h2><div class="paragraph"><p><code>java.util.concurrent.Flow</code></p></div>
<div class="paragraph"><p>JDK Standard of <a href="https://www.reactive-streams.org" class="bare">https://www.reactive-streams.org</a><br>
for <strong>asynchronous stream processing</strong><br>
with <strong>non-blocking backpressure</strong></p></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.2/README.md">Reactive Streams JVM Speciifcation</a></p></li></ul></div></div></div>
<aside class="notes"><div class="paragraph"><p>The main goal of Reactive Streams is to govern the exchange of stream data across an asynchronous boundary – think passing elements on to another thread or thread-pool — while ensuring that the receiving side is not forced to buffer arbitrary amounts of data.</p></div></aside></section><section id="_deprecation_of_finalize"><h2>Deprecation of <code>finalize()</code></h2><div class="quoteblock"><div class="title">Motivation</div><blockquote><div class="paragraph"><p>Finalizers are inherently problematic and their use can lead to performance
issues, deadlocks, hangs, and other problematic behavior.</p></div></blockquote></div>
<div class="openblock pc70 left fragment"><div class="content"><div class="paragraph"><p>No <code>forRemoval=true</code> yet — probably for long!</p></div></div></div>
<div class="openblock pc70 left tgap decent fragment x-small"><div class="content"><div class="paragraph"><p>New way: Register <code>Cleaner</code> services for your objects.<br>
They will receive <code>PhantomReference</code> to objects which are no longer reachable.</p></div></div></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="https://bugs.openjdk.java.net/browse/JDK-8165641">JDK-8165641 Deprecate Object.finalize</a></p></li><li><p><a href="https://stuartmarks.wordpress.com/2017/04/17/deprecation-of-object-finalize/">Deprecation of Object.finalize()</a></p></li></ul></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>Problem: Calling <code>finalize()</code> on an object allows it “resurrection” → GC problem</p></li><li><p>are <code>notforremoval</code> and probably for long. Port all JDK and then wait for important lcients to follow</p></li></ul></div></aside></section><section id="_string_enhancements" class="bonuscontent"><h2>String enhancements</h2><div class="title">Java 11: Adopting new <code>Character.isWhitespace()</code></div><pre class="highlight listingblock"><code data-noescape class="java language-java">" \tword\u0019 \r".trim() // → "word"; (Java 8)
// New methods based on `Character.isWhitespace(char)`
" \tword\u0019 \r".strip() // → "word\u0019"
" \tword\u0019 \r".stripLeading() // → "word\u0019 \r"
" \tword\u0019 \r".stripTrailing() // → " \tword\u0019"
" \t".isBlank() // → true</code></pre>
<div class="title">Java 12 utilities <span class="version">12</span></div><pre class="highlight listingblock"><code data-noescape class="java language-java">"hi\r\n you!".indent(2) // → " hi\n you!\n");
"hi\r\n you!".indent(-1) // → "hi\n you!\n");
Stream<String> l = "1\n2\n3\n!".lines();
IntStream stream = "word".chars();
"ABC".transform(String::toLowerCase), "abc");</code></pre>
<aside class="notes"><div class="ulist"><ul><li><p>Indents: Obviously eat-your-own-dogfood Preparation to Text Block. More in 13</p></li></ul></div></aside></section><section id="_jdk_api_changes" class="small lightbg" data-background-video="videos/api-diff-scroll.mp4" data-background-opacity="0.6"><h2><span class="icon"><i class="fa fa-tags"></i></span> JDK API Changes</h2><div class="paragraph"><p><a href="https://github.com/marchof/java-almanac">JDK API Changes Java Almanac</a></p></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p>Source: <a href="https://github.com/marchof/java-almanac">Java Almanac (Marc R. Hoffmann)</a></p></li><li><p><a href="https://github.com/AdoptOpenJDK/jdk-api-diff">Event more detailed API comparison</a></p></li></ul></div></div></div></section></section>
<section><section id="_tooling" class="lightbg" data-background-video="videos/hammer.mp4" data-background-video-loop data-background-opacity="0.7"><h2>Tooling</h2></section><section id="_repls_jshell_jep_222" data-background-size="contain" data-background-video="videos/jshell-demo.mp4"></section><section id="_repls_jshell_jep_222_2"><h2>REPLS: <code>jshell</code> <span class="jep"><a href="https://openjdk.java.net/jeps/222">JEP 222</a></span></h2><pre class="highlight listingblock small col2"><code data-noescape>$ jshell
| Welcome to JShell -- Version 13-ea
| For an introduction type: /help intro
jshell> "HI"
$1 ==> "HI"
jshell> var hi = $1.to
toCharArray() toLowerCase( toString() toUpperCase(
jshell> var hi = $1.toLowerCase()
hi ==> "hi"
jshell> String twice(String s) {
...> return s + s;
...> }
| created method twice(String)
jshell> var hihi = twice(hi)
hihi ==> "hihi"
jshell> /vars
| String $1 = "HI"</code></pre>
<pre class="highlight listingblock small col2"><code data-noescape>| String hi = "hi"
| String hihi = "hihi"
jshell> /methods
| String twice(String)
jshell> /edit twice
| modified method twice(String)
jshell> /list
1 : "HI"
2 : var hi = $1.toLowerCase();
4 : var hihi = twice(hi);
5 : String twice(String s) {
return "Double Time: "+ s + s;
}
jshell> /4
var hihi = twice(hi);
hihi ==> "Double Time: hihi"
jshell> /save twice twice.jsh</code></pre>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="https://docs.oracle.com/javase/10/jshell/introduction-jshell.htm">Java Shell User’s Guide</a></p></li><li><p><a href="https://www.pluralsight.com/guides/getting-started-with-jshell-part-2">Getting Started with JShell Part 2 & 3</a></p></li></ul></div></div></div></section><section id="_single_source_file_launch_jep_330"><h2>Single Source File Launch <span class="jep"><a href="https://openjdk.java.net/jeps/330">JEP 330</a></span></h2><div class="title">Directly execute Java source in File <code>hello</code> (no <code>.java</code>-Suffix!)</div><pre class="highlight listingblock"><code data-noescape class="java language-java">#!/usr/bin/java --source 11
public class SingleClassJava {
public static void main(String[] args) {
System.out.println("Hello " + args[0] + ". Executable .java – Yay!");
}
}</code></pre>
<div class="openblock fragment"><div class="content"><pre class="highlight listingblock"><code data-noescape class="bash language-bash">$ chmod +x hello
$ ./hello world
Hello world. Executable .java – Yay!</code></pre></div></div>
<div class="openblock fragment"><div class="content"><div class="paragraph"><p><span class="x-small decent">or launch any single-class Java file:</span></p></div>
<pre class="highlight listingblock"><code data-noescape class="bash language-bash">$ java SingleClassJava.java world</code></pre></div></div></section><section id="_jvm_logging_log_rerouting" class="left"><h2>JVM Logging & Log rerouting</h2><div class="title">Fine-grained, easy-to-configure JVM Logging <span class="jep"><a href="https://openjdk.java.net/jeps/158">JEP 158</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/271">JEP 271</a></span></div><pre class="highlight listingblock small"><code data-noescape>$ java -Xlog:os="debug,gc*=debug:stdout:pid,level,tags" SingleClassJava.java
[30911][debug][os] Initial active processor count set to 4
[30911][info ][os] Use of CLOCK_MONOTONIC is supported
[30911][debug][gc,ergo,heap ] Attempt heap expansion (allocate archive regions). Total size: …
[30911][info ][gc,cds ] Mark closed archive regions in map: [0x00000007bff00000, … ]</code></pre>
<div class="openblock tgap fragment"><div class="content"><div class="paragraph"><div class="title">JVM Log rerouting <span class="jep"><a href="https://openjdk.java.net/jeps/264">JEP 264</a></span></div><p>Allows applications to provide <strong>custom logger</strong> implementations<br>
to be <strong>used by platform</strong> classes.</p></div></div></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="https://grokonez.com/java/java-9/java-9-platform-logging-and-service">Java 9 Platform Logging API and Service</a></p></li><li><p><a href="https://grokonez.com/java/java-9/java-9-unified-jvm-logging">Java 9 Unified JVM Logging</a></p></li></ul></div></div></div></section><section id="_flight_recorder_jep_328"><h2>Flight Recorder <span class="jep"><a href="https://openjdk.java.net/jeps/328">JEP 328</a></span></h2><div class="paragraph"><p><span class="image" style="float: right"><img src="images/java-mission-control-center.png" alt="Java Mission Control" width="800"></span></p></div>
<div class="ulist"><ul><li><p><span class="icon"><i class="fa fa-cogs"></i></span> <strong>Production</strong>-<br>
Profiling & Monitoring</p></li><li><p>Former Oracle payware <br>
Open-sourced with Java 11</p></li><li><p><em>Flight recording</em> start<br>
on new & running <code>java</code></p></li><li><p>Rules → Alerts</p></li></ul></div>
<aside class="notes"><div class="ulist"><ul><li><p>low-overhead !</p></li><li><p>previously a commercial addition to the JVM, now open-sourced, part of Java 11</p></li><li><p><code>java -XX:StartFlightRecording=settings=default nl.craftsmen.java11demo.MyClass</code></p></li></ul></div></aside>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="http://jdk.java.net/jmc/" class="bare">http://jdk.java.net/jmc/</a></p></li></ul></div></div></div></section><section id="_microbenchmark_suite_jep_230_12"><h2>Microbenchmark Suite <span class="jep"><a href="https://openjdk.java.net/jeps/230">JEP 230</a></span> <span class="version">12</span></h2><div class="openblock col3-lc"><div class="content"><pre class="highlight listingblock small source"><code data-noescape class="java language-java">@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@State(Scope.Thread)
public class BenchmarkIntegers {
@Param("500")
private int size;
private String[] strings;
@Setup
public void setup() {
Random r = new Random(0);
strings = new String[size];
for (int i = 0; i < size; i++) {
strings[i] = "" + (r.nextInt(10000) - 5000);
}
}
@Benchmark
public void parseInt(Blackhole bh) {
for (String s : strings) {
bh.consume(Integer.parseInt(s));
}
}
}</code></pre></div></div>
<div class="openblock col3-r small"><div class="content"><div class="ulist"><ul><li><p>Based on <code>jmh</code></p></li><li><p>Avoids JIT Falltrips</p></li><li><p>Start via Maven Archteype</p></li></ul></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>Microbenchmarking: Falltrip JIT Compiler</p></li></ul></div></aside></section><section id="_jlink_jdeps_jep_282_jep_220_jep_275_jep_200_jep_201_jep_260" class="left"><h2><code>jlink</code> / <code>jdeps</code> <span class="jep"><a href="https://openjdk.java.net/jeps/282">JEP 282</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/220">JEP 220</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/275">JEP 275</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/200">JEP 200</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/201">JEP 201</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/260">JEP 260</a></span></h2><div class="quoteblock"><blockquote><div class="paragraph"><p><strong>Most interesting Part of Java 9 / Jigsaw!</strong></p></div></blockquote></div>
<div class="paragraph tgap"><div class="title">Minimize size with <code>jlink</code> Linker</div><p><span class="x-small">Build optimized, slim run-time image for modular Java application with minimal JRE</span></p></div>
<div class="paragraph"><div class="title">List package dependencies with <code>jdeps</code></div><p><span class="x-small"><code>jdeps app.jar</code></span></p></div>
<div class="openblock fragment"><div class="content"><div class="paragraph"><div class="title">+ better Container-Awareness</div><p><span class="x-small">Support of <strong>Docker</strong> CPU and memory limits.</span></p></div></div></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="http://cr.openjdk.java.net/~mr/jigsaw/ea/module-summary.html">JVM Module Summary</a></p></li><li><p><a href="http://openjdk.java.net/projects/jigsaw/spec/sotms/">The State of the Module System</a></p></li><li><p><a href="https://docs.oracle.com/en/java/javase/12/tools/jdeps.html">jdeps Manual</a></p></li><li><p><a href="https://bugs.openjdk.java.net/browse/JDK-8146115">JDK-8146115[Improve docker container detection</a></p></li></ul></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>Java 8 is not aware of being executed in a Docker container: Misinterpretation of available CPU / Memory can cause excessive CPU context switches, Thread contention, Memory overcomitting</p></li></ul></div></aside></section><section id="_packaging" class="left"><h2>Packaging</h2><div class="paragraph"><div class="title"><span class="icon"><i class="fa fa-book-dead"></i></span> Cross compilation with <code>javac --release N</code> <span class="jep"><a href="https://openjdk.java.net/jeps/247">JEP 247</a></span></div><p>Conveniently compile for older Java with <code>--release</code><br>
<span class="decent">Replaces: <code>javac -source N -target N –bootclasspath rtN.jar</code></span></p></div>
<div class="openblock tgap fragment"><div class="content"><div class="paragraph"><div class="title"><span class="icon"><i class="fa fa-cube"></i></span> Packaging: Multi-release JAR <span class="jep"><a href="https://openjdk.java.net/jeps/238">JEP 238</a></span></div><p>JAR Files can now contain multiple, version-specific versions classes</p></div></div></div></section><section id="_html5_javadoc_jep_221_jep_224_jep_225" class="bonuscontent"><h2>HTML5 Javadoc <span class="jep"><a href="https://openjdk.java.net/jeps/221">JEP 221</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/224">JEP 224</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/225">JEP 225</a></span></h2><div class="ulist"><ul><li><p>Enable via <code>-html5</code> parameter</p></li><li><p>Search box for easy navigation</p></li><li><p>HTML5 output; no more frames</p></li><li><p>Improved DocLint: <code>-Xdoclint/package:java.<strong>,javax.</strong></code></p></li></ul></div></section><section id="_performance"><h2>Performance</h2><div class="ulist"><div class="title">Compact Strings <span class="jep"><a href="https://openjdk.java.net/jeps/254">JEP 254</a></span></div><ul><li><p>Use ISO-8869-1 (1 byte/character) when possible</p></li></ul></div>
<div class="ulist"><div class="title">Garbage Collector G1 <span class="jep"><a href="https://openjdk.java.net/jeps/248">JEP 248</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/307">JEP 307</a></span></div><ul><li><p>Now default GC</p></li><li><p>Multi-threaded Full GCs</p></li><li><p>Minimzes Stop-the-world Pauses</p></li><li><p>Deduplicates String</p></li></ul></div>
<div class="ulist"><div class="title">Epsilon GC</div><ul><li><p>No-Op Garbage Collector (short-living JVMs)</p></li></ul></div></section></section>
<section><section id="_java_14_beyond" class="lightbg" data-background-video="videos/prediction.mp4" data-background-video-loop data-background-opacity="1"><h2>Java 14 & beyond</h2></section><section id="_project_metropolis"><h2>Project Metropolis</h2><div class="imageblock" style=""><img src="images/graalvm-architecture.png" alt="GraalVM ecosystem"></div>
<aside class="notes"><div class="ulist"><ul><li><p>Polyglot VM: Execute multiple language with zero overhead</p></li><li><p>Can run in multiple environments; Can produce native images</p></li><li><p>Zero-overhead interop</p></li></ul></div></aside></section><section id="_graalvmpolyglot_vm_jep_243_jep_246_jep_295"><h2>GraalVM — Polyglot VM <span class="jep"><a href="https://openjdk.java.net/jeps/243">JEP 243</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/246">JEP 246</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/295">JEP 295</a></span></h2><div class="openblock col2"><div class="content"><div class="ulist"><ul><li><p><strong>Ahead-of time compiler</strong> (AoT)</p></li><li><p>Generic VM<br>
for <strong>different languages</strong><br>
→ <em>JVM</em> (Java, Kotlin, Scala, …)<br>
→ <em>LLVM</em> (C, C++) → native<br>
→ <em>Java</em> Script, Python, Ruby, R</p></li></ul></div></div></div>
<div class="openblock col2"><div class="content"><div class="ulist"><ul><li><p>Shared Runtime → Zero overhead for language interop</p></li><li><p><strong>Native executables</strong><br>
(GraalVM on SubstrateVM)<br>
→ Much smaller startup & memory</p></li></ul></div></div></div>
<div class="openblock clear decent"><div class="content"><div class="paragraph"><div class="title">AoT can be used today:</div><p><span class="x-small"><code>java -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler</code></span></p></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>Multiple parts:</p><div class="ulist"><ul><li><p>AoT Compiler</p></li><li><p>Graal VM / Substrate VM as runtime</p></li></ul></div></li><li><p>AoT → improved startup time vs. JIT</p></li><li><p>Limitations: Dynamic (Reflection); highly experimental</p></li><li><p>AoT Compile can be used today</p></li></ul></div></aside></section><section id="_simplyfing_syntax_amber"><h2>Simplyfing Syntax: Amber</h2><div class="title">Pattern matching for <code>instanceof</code> <span class="jep"><a href="https://openjdk.java.net/jeps/305">JEP 305</a></span></div><pre class="highlight listingblock"><code data-noescape class="java language-java">if (obj instanceof String s) {
return s.contains("abc")
}</code></pre>
<div class="title">Unamed lamda parameters <span class="jep"><a href="https://openjdk.java.net/jeps/302">JEP 302</a></span></div><pre class="highlight listingblock"><code data-noescape class="java language-java">(i, _) -> String.valueOf(i);</code></pre>
<div class="title">Data Classes & Sealed Types</div><pre class="highlight listingblock"><code data-noescape class="java language-java">record Point(int x, int y) { }</code></pre>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="https://openjdk.java.net/projects/amber/">OpenJDK Project Amber</a></p></li><li><p><a href="https://cr.openjdk.java.net/~briangoetz/amber/datum.html">Data Classes and Sealed Types for Java</a></p></li></ul></div></div></div></section><section id="_value_types_valhalla"><h2>Value Types: Valhalla</h2><div class="quoteblock"><blockquote><div class="paragraph"><p>JVM infrastructure for working with <strong>immutable</strong> and <strong>reference-free</strong> objects,
for efficient by-value computation with non-primitive types.</p></div></blockquote></div>
<div class="openblock tgap"><div class="content"><div class="title">Value Object: Immutable & Final</div><pre class="highlight listingblock"><code data-noescape class="java language-java">value class Rectangle { int width,height; }</code></pre></div></div>
<div class="openblock decent tgap small"><div class="content"><div class="paragraph"><p><em>t(L1(/L2 Cache)</em> << <em>t(RAM)</em>: → Similar performance to primitives<br>
Benefits of immutables: Functional-style computations, shareability, …</p></div></div></div>
<div class="openblock refs"><div class="content"><div class="ulist"><ul><li><p><a href="https://openjdk.java.net/projects/valhalla/">OpenJDK Valhalla</a></p></li></ul></div></div></div></section><section id="_loom_fibers_continuations"><div class="paragraph"><p><span class="image"><img src="images/loom_banner1.png" alt="Loom: Fibers & Continuations"></span></p></div>
<div class="openblock col3-l"><div class="content"><div class="ulist"><div class="title">Lightweight concurrency</div><ul><li><p>Continuations</p></li><li><p>Fibers (JVM „threads“)</p></li><li><p>Tail-call elimination</p></li></ul></div></div></div>
<div class="openblock col3-cr"><div class="content"><pre class="highlight listingblock source small"><code data-noescape class="java language-java">Continuation cont = new Continuation(SCOPE, () -> {
while (true) {
System.out.println("before");
Continuation.yield(SCOPE);
System.out.println("after");
}
});
while (!cont.isDone()) {
cont.run();
}</code></pre>
<div class="paragraph"><p><span class="decent xx-small">Similar to cooperative multitasking or Kotlin’s Coroutines…</span></p></div></div></div>
<aside class="notes"><div class="ulist"><ul><li><p>User-mode "threads": No real theads & overhead</p></li><li><p>Continuations / Cooperative Multitasking: Tasks indicate when they want togive up control</p></li><li><p>Easily scales to 100.000 of parallel tasks</p></li></ul></div></aside></section></section>
<section id="_bottom_line" data-background-image="images/tweet-jdk-evolving.png"><aside class="notes"><div class="ulist"><ul><li><p>Geändertes Modell hat das Potential schnellere Features auch im Einsatz zu sehen
Generell: <strong>„Neuer Wind“ = Gute & überfällige Sache</strong>:</p><div class="olist arabic"><ol class="arabic"><li><p>Java wird wieder moderner. Die JVM war immer zeitgemäß</p></li><li><p>Schnellere Änderungen; <strong>Kampf gegen: "Java das neue COBOL!"</strong></p></li></ol></div></li><li><p>Try to get on the release train now! <strong>Just run: It might just work</strong></p></li><li><p>Many things devs want. But how convince management? → <strong>Saving Money!</strong> (Performance, Licence, Recruiting)</p></li><li><p>Adress compiler warnings: More seriously. Deprecation warnings will become true!</p></li></ul></div></aside></section>
<section><section id="_resources" class="lightbg" data-background-video="videos/industrial.mp4" data-background-video-loop data-background-opacity="0.6"><h2>Resources</h2><div class="openblock col3-l xx-small"><div class="content"><div class="ulist"><div class="title">References</div><ul><li><p><a href="https://github.com/marchof/java-almanac">JDK API Changes Java Almanac</a></p></li><li><p><a href="https://chriswhocodes.com/vm-options-explorer.html">VM Options Explorer for HotSpot, Graal, OpenJ9, Xing</a></p></li></ul></div>
<div class="ulist"><div class="title">Articles</div><ul><li><p><a href="https://medium.com/@javachampions/java-is-still-free-2-0-0-6b9aa8d6d244">Java is Still Free 2.0.3</a></p></li><li><p><a href="https://blogs.oracle.com/java-platform-group/oracle-jdk-releases-for-java-11-and-later">Oracle Blog: Oracle JDK</a></p></li><li><p><a href="https://www.pluralsight.com/guides/getting-started-with-jshell-part-2">Getting Started with <code>jshell</code> Part 2 & 3</a></p></li></ul></div>
<div class="ulist"><div class="title">OpenJDK Suppliers</div><ul><li><p><a href="https://adoptopenjdk.net/">AdoptOpenJDK</a>
<a href="https://access.redhat.com/articles/1299013">Red Hat</a>
<a href="https://aws.amazon.com/corretto/">Amazon Corretto</a>,
<a href="https://github.com/alibaba/dragonwell8">Alibaba</a>,
<a href="https://www.azul.com/products/zulu-enterprise/">Azul Zulu</a>,
<a href="https://github.com/SAP/SapMachine">SAP</a>,
<a href="https://www.ibm.com/marketplace/support-for-runtimes">IBM</a>,
<a href="https://bell-sw.com/java.html">BellSoft</a>,
<a href="https://www.jclarity.com/">jClarity</a></p></li></ul></div>
<div class="ulist"><div class="title">Tools</div><ul><li><p><a href="https://www.graalvm.org/">GraalVM</a></p></li><li><p><a href="http://jdk.java.net/jmc/">Flight Recorder/Mission Control Center (EAP)</a></p></li></ul></div></div></div><div class="openblock col3-c xx-small"><div class="content"><div class="ulist"><div class="title">Contact</div><ul><li><p>Twitter <a href="https://twitter.com/bentolor"><strong>@bentolor</strong></a></p></li><li><p>Email: <a href="mailto:[email protected]">[email protected]</a></p></li></ul></div>
<div class="ulist"><div class="title">Sources</div><ul><li><p><span class="icon"><i class="fa fa-code-branch fa-Github"></i></span> <a href="https://github.com/bentolor/java9to13"><strong>GitHub Repo with Source Code Examples & Slide Sources</strong></a></p></li></ul></div>
<div class="ulist"><div class="title">Image & Video Source</div><ul><li><p><a href="https://de.freeimages.com/photographer/s_lim363-49742">Background image</a>,
<a href="https://www.pexels.com/video/a-bee-on-a-yellow-flower-2048452/">Flowers</a>, <a href="https://www.pexels.com/video/relaxing-at-the-beach-1449880/">Relaxing at the beach</a>, <a href="https://www.pexels.com/video/cup-of-coffee-on-top-of-coffee-beans-855414/">Coffee Beans</a>, <a href="https://www.pexels.com/video/close-up-video-of-a-woman-studying-855418/">Woman studying</a>, <a href="https://www.pexels.com/video/white-keyboard-2219383/">White keyboard</a>, <a href="https://www.pexels.com/video/jack-hammering-pavement-855956/">Jackhammer</a>, <a href="https://www.pexels.com/video/globe-plasma-light-1192113/">Plasma Light</a>, <a href="https://www.pexels.com/video/heavy-equipment-loading-cement-2073130/">Industrial Site</a></p></li></ul></div></div></div><div class="openblock col3-r small"><div class="content"><div class="paragraph"><p><strong>These slides with all links</strong>
<span class="image"><img src="images/bentolor-java913-url-qrcode.png" alt="https://bentolor.github.io/java9to13/"></span><br>
<span class="emphasize"><strong><a href="https://bit.ly/2KPvyZh" class="bare">https://bit.ly/2KPvyZh</a></strong></span></p></div></div></div></section><section id="_cleanups" class="bonuscontent"><h2>Cleanups</h2><div class="openblock col2 x-small"><div class="content"><div class="ulist"><div class="title">JDK: Cleanup</div><ul><li><p><strong>Java EE removed</strong></p></li><li><p><strong>CORBA removed</strong></p></li><li><p>Internal API’s (<code>sun.*</code>) removed / deprecated</p></li><li><p><code>apple.applescript</code> & <code>com.apple</code> removed</p></li><li><p>Disable X.509/SHA-1 certificate chains</p></li><li><p>Remove Launch-Time JRE Version Selection directives</p></li><li><p><strong>Removed <code>Thread.destroy()</code> and <code>Thread.stop()</code></strong></p></li><li><p>Deprecate Applet API</p></li><li><p>Deprecate Nashorn Javascript Engine</p></li><li><p><strong>Deprecate Object.finalize()</strong></p></li></ul></div></div></div>
<div class="openblock col2 x-small"><div class="content"><div class="ulist"><div class="title">Language: Cleanup</div><ul><li><p><code>var</code> & <code>_</code> no longer a valid identifier</p></li></ul></div>
<div class="ulist"><div class="title">Tooling/JVM: Cleanup</div><ul><li><p>Remove <code>jhat</code></p></li><li><p>Remove hprof Agent</p></li><li><p>Remove old GC Combinations</p></li><li><p>Remove <code>javah</code></p></li><li><p>Remove <code>lib/endorsed</code> & <code>lib/ext</code></p></li><li><p><strong>Replace rt.jar</strong></p></li><li><p>ResourceBundle loads properties files in UTF-8 instead of ISO-8859-1</p></li><li><p>Deprecate CMS GC</p></li><li><p>Deprecate Pack200</p></li></ul></div></div></div></section><section id="_security_tls_crypto" class="bonuscontent"><h2>Security / TLS / Crypto</h2><div class="ulist"><ul><li><p>Validate Incoming Serialization Data
JDK 9</p></li><li><p>Default keystore type is the standard PKCS12 instead of the proprietary JKS
JDK 9</p></li><li><p>Default set of root Certification Authority (CA) certificates are provided with the JDK, so TLS connections are working out of the box
JDK 10</p></li><li><p>DRBG-Based SecureRandom
JDK 9</p></li><li><p>Disable X.509 certificate chains with SHA-1 based signatures
JDK 9</p></li><li><p>SHA-3 Hash Algorithms
JDK 9</p></li><li><p>TLS 1.3 support
JDK 11</p></li><li><p>API for Datagram Transport Layer Security (DTLS)
JDK 9</p></li><li><p>OCSP stapling TLS to improve performance of certificate status checking
JDK 9</p></li><li><p>TLS Application-Layer Protocol Negotiation (ALPN) Extension which enables protocol negotiation without additional round trips; ALPN is a requirement for HTTP/2 connections
JDK 9</p></li><li><p>Key Agreement with Curve25519 and Curve448
JDK 11</p></li><li><p>ChaCha20 and Poly1305 Cryptographic Algorithms
JDK 11</p></li></ul></div></section><section id="_internationalization" class="bonuscontent"><h2>Internationalization</h2><div class="ulist"><ul><li><p>ResourceBundle loads properties files <em>by default</em> in UTF-8 instead of ISO-8859-1.<br>
Overide via system property <code>java.util.PropertyResourceBundle.encoding</code> <span class="jep"><a href="https://openjdk.java.net/jeps/226">JEP 226</a></span></p></li><li><p>Unicode 10.0, adding roughly 27.000 characters, 10 blocks, and more than 30 scripts. <span class="jep"><a href="https://openjdk.java.net/jeps/267">JEP 267</a></span> <span class="jep"><a href="https://openjdk.java.net/jeps/327">JEP 327</a></span></p></li><li><p>java.util.Locale and related APIs support currency type, time zone and more. <span class="jep"><a href="https://openjdk.java.net/jeps/314">JEP 314</a></span></p></li><li><p><code>Locale</code>-specific operations now uses by default data provided by Unicode, no longer Oracle-provided. <span class="jep"><a href="https://openjdk.java.net/jeps/252">JEP 252</a></span></p></li></ul></div></section><section id="_graphics_and_desktop_applications" class="bonuscontent"><h2>.Graphics and Desktop Applications</h2><div class="ulist"><ul><li><p>Desktop features for all platforms like login/logout/lock event listener and task bar interactions
JDK 9</p></li><li><p>MultiResolutionImage that makes easy to retrieve a resolution-specific image for a DPI
JDK 9</p></li><li><p>HiDPI Graphics on Windows and Linux
JDK 9 <a href="https://openjdk.java.net/jeps/263" class="bare">https://openjdk.java.net/jeps/263</a></p></li><li><p>Enable GTK 3 on Linux for JavaFX, Swing, and AWT
JDK 9 <a href="https://openjdk.java.net/jeps/283" class="bare">https://openjdk.java.net/jeps/283</a></p></li><li><p>Replace @beaninfo Javadoc tags with @BeanInfo annotations for Swing
JDK 9</p></li><li><p>Update GStreamer included in JavaFX/Media to version 1.4.4
JDK 9</p></li><li><p>Replace the existing ICU OpenType font-layout engine with HarfBuzz
JDK 9</p></li></ul></div>
<script src="./live.js"></script>
<!-- hide "verbatim" sections if URL contains "terse"-Keyword -->
<script>
if (!window.location.search.match(/bonus/gi)) {
var sections = document.getElementsByTagName('section');
for (var i = sections.length-1; i > -1; --i) {
console.log(sections[i].classList);
if (sections[i].classList.contains("bonuscontent")) {
sections[i].remove();
}
}
}
</script></section></section></div></div><script src="reveal.js/lib/js/head.min.js"></script><script src="reveal.js/js/reveal.js"></script><script>Array.prototype.slice.call(document.querySelectorAll('.slides section')).forEach(function(slide) {
if (slide.getAttribute('data-background-color')) return;
// user needs to explicitly say he wants CSS color to override otherwise we might break custom css or theme (#226)
if (!(slide.classList.contains('canvas') || slide.classList.contains('background'))) return;
var bgColor = getComputedStyle(slide).backgroundColor;
if (bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent') {
slide.setAttribute('data-background-color', bgColor);
slide.style.backgroundColor = 'transparent';
}
})
// See https://github.com/hakimel/reveal.js#configuration for a full list of configuration options
Reveal.initialize({
// Display presentation control arrows
controls: true,
// Help the user learn the controls by providing hints, for example by
// bouncing the down arrow when they first encounter a vertical slide
controlsTutorial: true,
// Determines where controls appear, "edges" or "bottom-right"
controlsLayout: 'edges',
// Visibility rule for backwards navigation arrows; "faded", "hidden"
// or "visible"
controlsBackArrows: 'faded',
// Display a presentation progress bar
progress: true,
// Display the page number of the current slide
slideNumber: 'c/t',
// Control which views the slide number displays on
showSlideNumber: 'speaker',
// Push each slide change to the browser history
history: true,
// Enable keyboard shortcuts for navigation
keyboard: true,
// Enable the slide overview mode
overview: true,
// Vertical centering of slides
center: true,
// Enables touch navigation on devices with touch input
touch: true,
// Loop the presentation
loop: false,
// Change the presentation direction to be RTL
rtl: false,
// Randomizes the order of slides each time the presentation loads
shuffle: false,
// Turns fragments on and off globally
fragments: true,
// Flags whether to include the current fragment in the URL,
// so that reloading brings you to the same fragment position
fragmentInURL: true,
// Flags if the presentation is running in an embedded mode,
// i.e. contained within a limited portion of the screen
embedded: false,
// Flags if we should show a help overlay when the questionmark
// key is pressed
help: true,
// Flags if speaker notes should be visible to all viewers
showNotes: false,
// Global override for autolaying embedded media (video/audio/iframe)
// - null: Media will only autoplay if data-autoplay is present
// - true: All media will autoplay, regardless of individual setting
// - false: No media will autoplay, regardless of individual setting
autoPlayMedia: true,
// Number of milliseconds between automatically proceeding to the
// next slide, disabled when set to 0, this value can be overwritten
// by using a data-autoslide attribute on your slides
autoSlide: 0,
// Stop auto-sliding after user input
autoSlideStoppable: true,
// Use this method for navigation when auto-sliding
autoSlideMethod: Reveal.navigateNext,
// Specify the average time in seconds that you think you will spend
// presenting each slide. This is used to show a pacing timer in the
// speaker view
defaultTiming: 55,
// Enable slide navigation via mouse wheel
mouseWheel: true,
// Hides the address bar on mobile devices
hideAddressBar: true,
// Opens links in an iframe preview overlay
// Add `data-preview-link` and `data-preview-link="false"` to customise each link
// individually
previewLinks: false,
// Transition style (e.g., none, fade, slide, convex, concave, zoom)
transition: 'slide',
// Transition speed (e.g., default, fast, slow)
transitionSpeed: 'default',
// Transition style for full page slide backgrounds (e.g., none, fade, slide, convex, concave, zoom)
backgroundTransition: 'fade',
// Number of slides away from the current that are visible
viewDistance: 5,
// Parallax background image (e.g., "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'")
parallaxBackgroundImage: 'images/background-landscape-light-orange.jpg',
// Parallax background size in CSS syntax (e.g., "2100px 900px")
parallaxBackgroundSize: '4936px 2092px',
// Number of pixels to move the parallax background per slide
// - Calculated automatically unless specified
// - Set to 0 to disable movement along an axis
parallaxBackgroundHorizontal: null,
parallaxBackgroundVertical: null,
// The display mode that will be used to show slides
display: 'block',
// The "normal" size of the presentation, aspect ratio will be preserved
// when the presentation is scaled to fit different resolutions. Can be
// specified using percentage units.
width: 1408,
height: 792,
// Factor of the display size that should remain empty around the content
margin: 0.1,
// Bounds for smallest/largest possible scale to apply to content
minScale: 0.2,
maxScale: 1.5,
// Optional libraries used to extend on reveal.js
dependencies: [
{ src: 'reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'reveal.js/plugin/zoom-js/zoom.js', async: true },
{ src: 'reveal.js/plugin/notes/notes.js', async: true },
],
});</script></body></html>