5. Innovating for the Future
Panama
Improving and
enriching the
connections
between the Java
virtual machine
and well-defined
but “foreign”
(non-Java) APIs
Valhalla
Higher density and
performance of
machine learning
and big data
applications
through the
introduction of
inline classes.
Loom
Massively scale
lightweight
threads, making
concurrency
simple again.
Amber
Continuously
improve developer
productivity
through evolutions
of the Java
language.
Leyden
Address long-term
pain points of
Java’s start-up
time, time to peak
performance and
large footprint.
ZGC
Create a scalable
low latency
garbage collector
capable of
handling large
heaps.
openjdk.org
6. A Minimal Java Setup
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
☕ A JDK (includes JDK tools like javac and java)
☕ An Integrated Development Environment (IDE)
☕ A build tool (maven, gradle, basel etc)
☕ (Boilerplate) Java code
7. Towards a Simplified Beginning
☕ Use jshell for fast prototyping Java code
☕ Since JDK 11 you have single-file execution
java HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
8. Towards a Simplified Beginning
☕ Use jshell for fast prototyping Java code
☕ Since JDK 11 you have single-file execution
java HelloWorld.java
☕ JEP 458 proposes the ability to run a program supplied as
multiple files of Java code
java --class-path ‘*’ HelloWorld.java
// HelloWorld.java
class HelloWorld {
public static void main(String[] args) {
Helper.run();
}
}
// Helper.java
class Helper {
static void run() { System.out.println("Hello
World!");
}
}
10. Effective Scripting with Java
// HelloWorld.java
void main() {
Helper.run();
}
// Helper.java
class Helper {
static void run() { System.out.println("Hello
World!");
}
}
JEP 445 proposes to reduce mandatory Java concepts
☕ Class declaration no longer required
☕ main is not necessarily public static
☕ String[] args not declared if not used further
11. Invocation Order When Selecting Main
☕ A static void main(String[] args) method of non-private access in the launched class.
☕ A static void main() method with non-private access in the launched class.
☕ A non-private void main(String[] args) instance method in the launched class/inherited from a
superclass.
☕ A non-private void main() instance method in the launched class or inherited from a superclass.
12. So You Want to Know More…
☕ JEP 445:Unnamed Classes and Instance Main Methods(Preview)
☕ JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview)
☕ Script Java Easily in 21 and Beyond - Inside Java Newscast #49
☕ JEP 458: Launch Multi-File Source-Code Programs
14. Express Semantic Intent of Your Models
// Prior to Java 16
if (obj instanceof Postcard) {
Postcard p = (Postcard)obj;
... use p ...
}
// As of Java 16
if (obj instanceof Postcard p) {
... use p ...
}
15. Pattern Matching and Records
Intention intention = new Present(24.2, 1.5, “RON”);
// As of Java 16
if (intention instanceof Present p) {
double itemPrice = p.itemPrice();
double boxPrice = p.boxPrice();
System.out.println(itemPrice + boxPrice);
}
// As of Java 21
if (intention instanceof Present(double itemPrice, double boxPrice, Currency c)) {
System.out.println(itemPrice + boxPrice);
}
16. Wrapup Expressive Data Modeling
☕ A sender can do a nice gesture and offer a gift.
☕ A gift can be either a postcard or add to it one of
the following: an online coupon, buy an experience
or a material present.
☕ A postcard does not have an associated cost, all the
other 3 types of gifts have a price.
☕ An online coupon has an expiry date.
☕ A present can be placed inside a box.
☕ A sender can give a different postcard or surprise
depending on celebration, but never send 2
postcards as a gift.
17. Wrapup Expressive Data Modeling
☕ A common formatting process to JSON through
public sealed interface Intention
permits Coupon, Experience,
Present, Postcard {
//…
}
18. Wrapup Expressive Data Modeling
☕ A common formatting process to JSON through
public sealed interface Intention
permits Coupon, Experience,
Present, Postcard {
//…
}
☕ Coupon, Experience, Present, Postcard
are records
☕ Represent Gift using nested record patterns
19. Working With Nested Record Patterns
public record Postcard(String sender, String receiver, Celebration celebration)
implements Intention{}
public record Experience(double price, Currency currency)implements Intention{}
record Gift(Postcard postcard, Intention intention) {}
// As of Java 21
if (gift instanceof Gift(Postcard p, Experience e)) {
System.out.println("Price of experience is expressed in" + e.currency())
}
20. Working With Nested Record Patterns
public record Postcard(String sender, String receiver, Celebration celebration)
implements Intention{}
public record Experience(double price, Currency currency)implements Intention{}
record Gift(Postcard postcard, Intention intention) {}
// As of Java 21
if (gift instanceof Gift(Postcard p, Experience (double price, Currency c ))) {
System.out.println("Price of experience is expressed in" + c);
}
21. Working With Nested Record Patterns
public record Postcard(String sender, String receiver, Celebration celebration)
implements Intention{}
public record Experience(double price, Currency currency)implements Intention{}
record Gift(Postcard postcard, Intention intention) {}
// As of Java 21
if (gift instanceof Gift(var p, Experience (var price, Currency c ))) {
System.out.println("Price of experience is expressed in" + c);
}
22. So You Want To Know More…
☕ Clean Application Development with Records, Sealed Classes and Pattern Matching (2022)
☕ Java Records are "Trusted" and Consequently Faster
☕ Java 21 New Feature: Sequenced Collections - JEP Cafe #19
☕ JEP 440:Record Patterns
24. String Templates Components
String data = STR. """
{
"sender": "Ana",
"receiver": "Duke",
"celebration": "{ celebration}",
"option" : "{ Choice.NONE }"
}
""" ;
☕ A template processor (STR),
☕ A dot character (U+002E),
☕ A template which can contain an embedded
expression ({celebration}).
25. Use the Template Processor API
package java.lang;
public interface StringTemplate {
...
@FunctionalInterface
public interface Processor<R, E extends Throwable> {
R process(StringTemplate st) throws E;
}
...
}
26. Use the Template Processor API
public interface StringTemplate {
...
@FunctionalInterface
public interface Processor<R, E extends Throwable> {
R process(StringTemplate st) throws E;
}
...
} public sealed interface Intention
permits Coupon, Experience, Present, Postcard {
StringTemplate.Processor<JSONObject, RuntimeException> JSON = StringTemplate.Processor.of(
(StringTemplate st) -> new JSONObject(st.interpolate())
);
JSONObject asJSON();
}
27. Use the Template Processor API
public record Present(double itemPrice, double boxPrice, Currency currency)
implements Intention {
@Override
public JSONObject asJSON() {
return JSON. """
{
"currency": "{currency}",
"boxPrice": "{boxPrice}",
"packaged" : "{ boxPrice > 0.0}",
"cost": "{(boxPrice > 0.0) ? itemPrice + boxPrice : itemPrice}"
};
""" ;
}
}
28. Use the Template Processor API
public record Present(double itemPrice, double boxPrice, Currency currency)
implements Intention {
@Override
public JSONObject asJSON() {
return JSON. """
{
"currency": "{currency}",
"boxPrice": "{boxPrice}",
"packaged" : "{ boxPrice > 0.0}",
"cost": "{(boxPrice > 0.0) ? itemPrice + boxPrice : itemPrice}"
};
""" ;
}
}
29. Use the Template Processor API
public record Present(double itemPrice, double boxPrice, Currency currency)
implements Intention {
@Override
public JSONObject asJSON() {
return JSON. """
{
"currency": "{currency}",
"boxPrice": "{boxPrice}",
"packaged" : "{ boxPrice > 0.0}",
"cost": "{(boxPrice > 0.0) ? itemPrice + boxPrice : itemPrice}"
};
""" ;
}
}
30. So You Want to Know More…
☕ Interpolate Strings Like a King in Java 21 - Inside Java Newscast #47
☕ String Tapas Redux by Jim Laskey and Brian Goetz
☕ JEP 430: String Templates (Preview)
☕ JEP 459: String Templates (Second Preview)
☕ Stepping in 2024 with Powerful Java Language Features
32. Many Flavors Of Pattern Matching & Switch
☕ Test the equality of a variable against several values specified in the cases
☕ More expressiveness and utility of switch expressions
☕ Mitigate the strict null-handling behavior of switch
☕ Augment security of switch statements
☕ Guarantee backward compatibility for all existing switch expressions and statements
33. Let’s Add Some Style to Postcard
Font font = postcard.celebration().getStyle();
switch(font) {
case Style s when s == Style.BOLD -> {
System.out.println("It's bold");
}
case Style s when s == Style.REGULAR -> {
System.out.println("It's regular");
}
case Style s -> System.out.println("Other styles");
case Color c -> System.out.println("It's colored");
}
Since JDK 21
☕ No more parenthesized patterns
☕ Qualified enum constants can
be case constants in switch expressions
and statements.
34. Record Patterns and Exhaustive Switch
JSONObject process(Gift gift, Choice choice) {
return switch (gift) {
case Gift(Postcard p, Postcard p2) -> p.asJSON();
case Gift(Postcard p, Coupon c) when (c.price() == 0.0) -> p.asJSON();
case Gift(Postcard p, Experience e) when (e.price() == 0.0) -> p.asJSON();
case Gift(Postcard p, Present pr) when (pr.itemPrice() == 0.0) -> p.asJSON();
case Gift(Postcard p, Experience e) -> gift.merge(choice.name().toLowerCase());
case Gift(Postcard p, Present pr) -> gift.merge(choice.name().toLowerCase());
case Gift(Postcard p, Coupon c) -> gift.merge(choice.name().toLowerCase());
};
}
35. So You Want To Know More…
☕ State of Pattern Matching with Brian Goetz (2022)
☕ Pattern Matching in the Java Object Model
☕ Patterns: Exhaustiveness, Unconditionality, and Remainder
☕ JEP 441: Pattern Matching for switch
☕ Uniform handling of failure in switch
39. SequencedCollections
From First to Last and
Everything Reversed
JEP 431: Sequenced Collections: https://openjdk.org/jeps/431
Core Library
40. A World Without SequencedCollections
☕ Each collection gets first and last element in its own way
☕ Iterating in reverse varies across collection types
☕ Needs operations for a sequence of elements with a
defined encounter order
//intersection of 2 lists of numbers
Set<Integer> intersection = new HashSet<>(list1);
intersection.retainAll(list2);
if (list1.get(0).equals(list2.get(0))) {
intersection.add(list1.get(0));
}
int last = list1.size() - 1;
if (list1.get(last)
.equals(list2.get(list2.size() - 1))) {
intersection.add(list1.get(last));
}
41. Enter SequencedCollections
public interface SequencedCollection<E>
extends Collection<E> {
SequencedCollection<E> reversed();
default void addFirst(E e);
default void addLast(E e);
default E getFirst();
default E getLast();
default E removeFirst();
default E removeLast();
}
☕ A Collection with a defined encounter order
☕ Has first and last elements
☕ Supports operations at either end
☕ Entries between first and last have successors and ancestors
☕ Can process elements forward and reverse
42. Refactoring to SequencedCollections
☕ A Collection with a defined encounter order
☕ Uniform access to first and last element
☕ Supports operations at either end
☕ Entries between first and last have successors and
ancestors
☕ Can process elements forward and reverse
//intersection of 2 lists of numbers
Set<Integer> intersection = new HashSet<>(list1);
intersection.retainAll(list2);
if (list1.getFirst().equals(list2.getFirst())) {
intersection.add(list1.getFirst());
}
if (list1.getLast().equals(list2.getLast())) {
intersection.add(list1.getLast());
}
43. So You Want To Know More…
☕ Inside Java Podcast Episode 31 “Sequenced Collections” with Stuart Marks
☕ Java 21's New (Sequenced) Collections - Inside Java Newscast #45
☕ Java 21 New Feature: Sequenced Collections - JEP Cafe #19
45. ZGC at a Glance
☕ Delivered in JDK 15 (September 2020)
☕ A scalable low-latency garbage collector
☕ Handling heap sizes from 8MB to 16TB
☕ Auto-tuning: requires minimal configuration
Pause Mark Start Pause Mark End Pause Relocate Start
Concurrent
Mark/Remap
Concurrent
Prepare for
Relocate
Concurrent
Relocate
GC Cycle
pauses are O(1)
46. Benefits of Generational ZGC
☕ Withstand higher allocation rates
☕ Lower heap headroom
☕ Lower CPU usage
☕ Starting with JDK 21 can be enabled using -XX:+UseZGC -XX:+ZGenerational
☕ Automatic Tuning - Only set the max heap size! (-Xmx)
47. Reduced latency in G1GC
☕ JNI includes critical accessor functions.
☕ The JVM must not move a Java thread that is in a critical region
☕ Lock an object in place as the GC moves other objects (pinning).
☕ JEP 423: Region Pinning for G1 targets JDK 22
Native Code
Functions
Libraries
JNI
GetPrimitiveArrayCritical
ReleasePrimitiveArrayCritical
Java Code
48. So You Want To Know More
☕ Introduction to ZGC
☕ Deep-dive of zgc's architecture
☕ JVMLS - generational ZGC and beyond
☕ Optimizing memory utilization with automated heap sizing in ZGC
☕ Z garbage collector: the next generation
☕ ZGC : java’s highly scalable low-latency garbage collector - stack walker #1
☕ Evacuation Failure and Object Pinning
50. Public Key Encryption (PKE)
☕ The sender encrypts a message using receiver's
public key .
☕ The receiver decrypts the message with their
private key.
☕ Brute force attacks on PKE data become practical
as quantum computing advances.
51. Key Encapsulation Mechanism (KEM)
☕ Generate a pair of keys (public, private).
☕ The sender creates an encapsulation using the public key.
☕ The sender uses KEM to transmit the shared key.
☕ Later the sender uses KEM to encrypt data
using
a symmetric algorithm.
☕ The receiver decrypts the encapsulation with its private key.
52. Key Encapsulation Mechanism API
☕ Key pair generation function
This function is already covered by the KeyPairGenerator API.
☕ Key encapsulation
Encapsulate(public_key) -> ciphertext, shared_secret
☕ Key decapsulation
Decapsulate(private_key, ciphertext) -> shared_secret
53. So You Want To Know More
☕ Java 21 Security #RoadTo21
☕ Strengthen your Java App's Defenses with Key Encapsulation Mechanism API - Inside Java Newscast #53
☕ JEP 452: Key Encapsulation Mechanism API
55. Virtual Threads Under the Hood
A thread managed
by JVM scheduler
can get a task
assigned by you.
Java scheduler
assigns the virtual
thread to platform
thread(s).
Virtual thread asks platform
thread(s) to perform the task.
If a virtual thread has some blocking
I/O operation, it will be detached from
the platform thread.
Another virtual thread is assigned to the
platform thread so that the platform thread
stays in a running state
56. Readable Code with Virtual Threads
Create one new virtual thread per task
Explicitly start a virtual thread
57. Maintanable Code with Virtual Threads
Explicitly start a virtual thread
Execute 1000 tasks
59. So you want to know more
☕ Virtual Threads: An Adoption Guide
☕ Java 21 new feature: Virtual Threads #RoadTo21
☕ JVMLS - The Challenges of Introducing Virtual Threads to the Java Platform by Alan Bateman
☕ JEP 444: Virtual Threads
61. Structured Concurrency Advantages
try (var scope = new StructuredTaskScope.ShutdownOnSuccess<Present>()) {
var offer1 = scope.fork(() -> readOffer1(refPrice, boxPrice));
var offer2 = scope.fork(() -> readOffer2(refPrice, boxPrice));
var offer3 = scope.fork(() -> readOffer3(refPrice, boxPrice));
var offer4 = scope.fork(() -> readOffer4(refPrice, boxPrice));
scope.join();
Present quickPresent = scope.result();
return quickPresent;
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
Obtain a present fast from the available offers
☕ Create relationship between threads
☕ Forked tasks are children of the scope
☕ Success/failure policy can be defined across
all children.
62. Structured Concurrency Advantages
try (var scope = new StructuredTaskScope.ShutdownOnSuccess<Present>()) {
var offer1 = scope.fork(() -> readOffer1(refPrice, boxPrice));
var offer2 = scope.fork(() -> readOffer2(refPrice, boxPrice));
var offer3 = scope.fork(() -> readOffer3(refPrice, boxPrice));
var offer4 = scope.fork(() -> readOffer4(refPrice, boxPrice));
scope.join();
Present quickPresent = scope.result();
return quickPresent;
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
Obtain a present fast from the available offers
☕ Create relationship between threads
☕ Forked tasks are children of the scope
☕ Success/failure policy can be defined across
all children.
☕ Return the result of the first subtask that
completed with a result.
63. Structured Concurrency Advantages
try (var scope = new StructuredTaskScope.ShutdownOnSuccess<Present>()) {
var offer1 = scope.fork(() -> readOffer1(refPrice, boxPrice));
var offer2 = scope.fork(() -> readOffer2(refPrice, boxPrice));
var offer3 = scope.fork(() -> readOffer3(refPrice, boxPrice));
var offer4 = scope.fork(() -> readOffer4(refPrice, boxPrice));
scope.join();
Present quickPresent = scope.result();
return quickPresent;
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
Obtain a present fast from the available offers
☕ Create relationship between threads
☕ Forked tasks are children of the scope
☕ Success/failure policy can be defined across
all children.
☕ Return the result of the first subtask that
completed with a result.
☕ Thread-dumps capture transparently the
relationship between threads.
64. Benefits for High Scaling Applications
Higher throughput with fewer CPU
operations when having high number
concurrent requests.
When having blocking calls, virtual threads
will go in a waiting state until they receive
data.
65. Experience Scoped Values
//in Wrapup record
ScopedValue.where(VALID_REQUEST, Choice.EXPERIENCE)
.call(() -> findOffer(data.itemPrice()));
// in Experience record
public Experience {
if (!VALID_REQUEST.isBound()) {
throw new IllegalStateException("not bound");
} else if (!VALID_REQUEST.get()
.equals(Choice.EXPERIENCE)) {
throw new IllegalStateException(VALID_REQUEST.get());
}
}
//…
Find the best in price experience
☕ Best experience for a valid request
66. Experience Scoped Values
public static class ExperienceScope
extends StructuredTaskScope<Experience> {
//…
try (var scope = new Experience.ExperienceScope()) {
scope.fork(() -> readOffer1(referencePrice));
scope.fork(() -> readOffer2(referencePrice));
scope.fork(() -> readOffer3(referencePrice));
scope.fork(() -> readOffer4(referencePrice));
scope.join();
return scope.findOffer();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//…
Find the best in price experience
☕ Best experience for a valid request
☕ Simplify reasoning about data flow
☕ The lifetime of shared data is visible from code
structure.
☕ Data shared by a caller can be retrieved only by
legitimate callees.
☕ Performance through immutable shared data.
67. So You Want To Know More
☕ Structured Concurrency
☕ On Parallelism and Concurrency
☕ Java 20 - From ThreadLocal to ScopedValue with Loom Full Tutorial - JEP Café #16
☕ JEP 453: Structured Concurrency (Preview)
☕ JEP 446: Scoped Values (Preview)
69. Project Leyden
☕ Faster Startup
Improving the time to get to the first useful unit of work.
☕ Better Warmup
Enhancing the time it takes for the application to reach peak performance.
☕ Provide a unifying conceptual model that lets developers choose how to trade off constraints for performance.
70. Improving Startup and Warmup
☕ Could shift computation work later in time, by utilizing laziness techniques.
☕ Could shift computation work earlier in time, from run time to build time.
☕ Shifting computation can be part of the application (e.g., running application or framework code), or on
behalf of the it (e.g., compiling application code).
☕ The JDK already has plenty of features that can shift computation.
71. Java Features that Can Shift Computation
☕ Using the normal semantics of Java programs
Compile-time constant folding (shifts earlier)
Garbage collection (later)
Lazy class loading and initialization (later)
☕ Some require the user to enable them
Experimental ahead-of-time (AOT) compilation (earlier)
Pre-digested class-data archives (CDS) (earlier)
72. Leyden conceptual model
Source https://openjdk.org/projects/leyden/slides/leyden-jvmls-2023-08-08.pdf
☕ Shift computation temporally, both later and earlier in time
☕ Constrain Java’s natural dynamism, if necessary to enable more and better shifting
☕ Selectively, per the needs of each particular program
☕ Compatibly, to preserve program meaning
73. Leyden progress
☕ Introduce condensers
Toward Condensers (design note, Brian Goetz, Mark Reinhold, & Paul Sandoz)
☕ Shift computation and constrain dynamism
Pre-generate lambda classes (prototype branch, Dan Heidinga)
Condensing Indy Bootstraps (design note, Brian Goetz)
Computed Constants (draft JEP, Per Ake Minborg & Maurizio Cimadamore)
Experiments in shifting speculative compilation (Rose et al.)
☕ Related improvements
Hermetic application packaging (prototype branch, Zhou)
JMOD-less linking (prototype, Gehwolf)
Source JVMLS - Project Leyden
75. Project Babylon
☕ Extend Java's reach to foreign programming models.
☕ Code reflection is fit for purpose of GPU programming domains.
☕ Easily implement support for a foreign coding model as a Java library.
☕ API to build, analyze, and transform code models.
76. So you want to know more
☕ https://mail.openjdk.org/pipermail/discuss/2023-September/006226.html
☕ JVMLS - Java and GPU … are we nearly there yet?
☕ JVMLS Code Reflection by Paul Sandoz
☕ Java on GPU
77. Stay Tuned for More!
Inside.java
Dev.java youtube.com/java