Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Learning modern Java the playful way (Devoxx PL)

Learning modern Java the playful way (Devoxx PL)

Modern Java can feel overwhelming. If you don’t have any experience with Java since Java 8 (or at all), features like structured concurrency or pattern matching might sound exciting, but also scary: “How do I even get started with that?”

Fear not! In this session Marit and Piotr will explain to you the new exciting things and also show you how to use them in your IDE, so that the next day you can start having fun and profit with modern Java in your favorite tools on your own.

* Talk with Piotr Przybył

Avatar for Marit van Dijk

Marit van Dijk

June 13, 2025
Tweet

More Decks by Marit van Dijk

Other Decks in Programming

Transcript

  1. $ who are we Piotr Przybył @piotrprz @piotrprz.bsky.social Senior Developer

    Advocate Marit van Dijk @MaritvanDijk77 @maritvandijk.bsky.social Developer Advocate
  2. Agenda • Various features from recent Java versions (not all

    of them, obviously) • Demos (obviously)
  3. CAVEAT AVDITORES A.K.A. Safe harbour statement: don't assume anything based

    on this presentation. Verify on your own. Errare humanum est.
  4. How to stay up to date with Java • Communities,

    conferences • Your local JUG: https://dev.java/community/jugs/ and/or the VirtualJUG: https://www.meetup.com/virtualjug/ • The JEPs: https://openjdk.org/jeps/0 • Blogs, like: ◦ 󰐤 JVM Bloggers: https://jvm-bloggers.com/ ◦ IntelliJ IDEA: https://blog.jetbrains.com/idea/ ◦ Software Garden: https://softwaregarden.dev/ ◦ Inside Java: https://inside.java/ • and many, many more
  5. Simple / Compact source files & Instance main methods 🧪

    Preview in Java 24 JEP 495 Standard feature in Java 25 JEP 512
  6. Simple / Compact source files & Instance main methods public

    class HelloWorld { public static void main(String[] args) { System.out.println("Witaj Świecie!"); } }
  7. Simple / Compact source files & Instance main methods public

    class HelloWorld { public static void main(String[] args) { System.out.println("Witaj Świecie!"); } }
  8. Simple / Compact source files & Instance main methods public

    class HelloWorld { public static void main(String[] args) { System.out.println("Witaj Świecie!"); } } void main() { println("Witaj Świecie!"); }
  9. final class QueryWithVector { private final String query; private final

    List<Float> vector; QueryWithVector(String query, List<Float> vector) { this.query = query; this.vector = vector; } @Override public String toString() { return "QueryWithVector[" + "query=" + query + ", " + "vector=" + vector + ']'; } public String getQuery() { return query; } public List<Float> getVector() { return vector; } @Override public boolean equals(Object obj) { if (obj -= this) return true; if (obj -= null -| obj.getClass() -= this.getClass()) return false; var that = (QueryWithVector) obj; return Objects.equals(this.query, that.query) -& Objects.equals(this.vector, that.vector); } @Override public int hashCode() { return Objects.hash(query, vector); } } record QueryWithVector(String query, List<Float> vector) { @Override public String toString() { return "QueryWithVector[" + "query=" + query + ", " + "vector=" + vector + ']'; } }
  10. 🧪 Preview in Java 24 JEP 495 Standard feature in

    Java 25 JEP 512 Simple / Compact source files & Instance main methods ▶ Also comes with simple IO
  11. Stream Gatherers Stream.of(...) .gather(a) [.gather(b)] [.gather(c)] .collect(...); custom intermediate operations

    Stream Gatherers - Deep Dive with the Expert: https://youtu.be/v_5SKpfkI2U Gatherers: The API Your Stream Was Missing: https://youtu.be/oVdWfU_IObY Hunting with Stream Gatherers: https://youtu.be/rvW8tu1n5x4 Extending Functional Pipelines with Gatherers: https://www.youtube.com/live/dxVDiJsyu3Y ▶
  12. Structured Concurrency • better "idioms" for multi-threaded code • synchronous

    way of thinking • help eliminate thread leaks and cancellation delays
  13. Task POST ${elasticsearch}/catalogue/_search { } “apple” POST ${elasticsearch}/catalogue/_search { }

    RRF Results: 1. … 2. … 3. … 4. … Structured Concurrency Subtask Subtask combine Results: 1. … ▶
  14. static SearchResult executeSearch(QueryWithVector qwv, String indexName, ElasticsearchClient esClient) { try

    (var scope = new StructuredTaskScope.ShutdownOnFailure()) { var knnSearch = scope.fork(() -> performKnnSearch(qwv.vector(), indexName, esClient)); var classicSearch = scope.fork(() -> performClassicSearch(qwv.query(), indexName, esClient)); scope.join(); scope.throwIfFailed(); var combined = combineUsingRRF(List.of(knnSearch.get(), classicSearch.get()), 60, TOP_K); return new SearchResult(qwv.query(), combined); } catch (Exception e) { throw new RuntimeException(); } } static SearchResult executeSearch(QueryWithVector qwv, String indexName, ElasticsearchClient esClient) { try (var scope = StructuredTaskScope.open()) { var knnSearch = scope.fork(() -> performKnnSearch(qwv.vector(), indexName, esClient)); var classicSearch = scope.fork(() -> performClassicSearch(qwv.query(), indexName, esClient)); scope.join(); var combined = combineUsingRRF(List.of(knnSearch.get(), classicSearch.get()), 60, TOP_K); return new SearchResult(qwv.query(), combined); } catch (Exception e) { throw new RuntimeException(); } } Java 24 Java 25
  15. TL;DR: .open() with Joiner and Config, can (re)use thread pools,

    also platform ones Structured Concurrency: Java 24 vs 25 try (var scope = StructuredTaskScope.open( StructuredTaskScope.Joiner.awaitAllSuccessfulOrThrow(), config -> config .withName("myStructuredConcurrency") .withTimeout(Duration.ofSeconds(5)) .withThreadFactory(myThreadFactory))) { var subtask1 = scope.fork(() -> action(--.)); var subtask2 = scope.fork(this-:anotherAction); scope.join(); combineResults(subtask1.get(), subtask2.get()); }
  16. Markdown Documentation Comments Standard feature in Java 23 JEP 467

    • Easier to read & write Markdown in Java Docs? Shut Up and Take My Comments! https://blog.jetbrains.com/idea/2025/04/markdown-in-java-docs-shut-up-and-take-my-comments/ ▶
  17. Pattern matching 🧪 Preview in Java 24 JEP 488 🧪

    Preview in Java 25 JEP 507 • Allow primitive types in all pattern contexts • Extend instanceof and switch to work with all primitive types ▶
  18. Vector API (Panama) 🧫 Incubator in Java 24 JEP 489

    🧫 Incubator in Java 25 JEP 508 ▶
  19. $ docker exec -it es-local-dev /bin/sh -c "ps aux |

    cat" /usr/share/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j2.formatMsgNoLookups=true -Djava.locale.providers=CLDR -Dorg.apache.lucene.vectorization.upperJavaFeatureVersion=24 -Des.distribution.type=docker -Des.java.type=bundled JDK --enable-native-access=org.elasticsearch.nativeaccess,org.apache.lucene.core --enable-native-access=ALL-UNNAMED --illegal-native-access=deny -Des.cgroups.hierarchy.override=/ -XX:ReplayDataFile=logs/replay_pid%p.log -Des.entitlements.enabled=true -XX:+EnableDynamicAgentLoading -Djdk.attach.allowAttachSelf=true --patch-module=java.base=lib/entitlement-bridge/elasticsearch-entitlement-bridge-9.0.0.jar --add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement,java.lo gging,java.net.http,java.naming,jdk.net -XX:+UseG1GC -Djava.io.tmpdir=/tmp/elasticsearch-11578202498973800384 --add-modules=jdk.incubator.vector -Dorg.apache.lucene.store.defaultReadAdvice=normal -XX:+HeapDumpOnOutOfMemoryError -XX:+ExitOnOutOfMemoryError -XX:HeapDumpPath=data -XX:ErrorFile=logs/hs_err_pid%p.log -Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,level,pid,tags:filecount=32,filesize=64m -Xms128m -Xmx2g -XX:MaxDirectMemorySize=1073741824 -XX:G1HeapRegionSize=4m -XX:InitiatingHeapOccupancyPercent=30 -XX:G1ReservePercent=15 --module-path /usr/share/elasticsearch/lib --add-modules=jdk.net --add-modules=jdk.management.agent --add-modules=ALL-MODULE-PATH -m org.elasticsearch.server/org.elasticsearch.bootstrap.Elasticsearch ▶
  20. What did we play with? Vectors from Panama Records Structured

    Concurrency Stream Gatherers Pattern Matching Compact Classes, module imports, simple IO … and more
  21. Each new Java version is: • easier • faster •

    better • and (guess what?) still free Why not use it?
  22. Thank you! Bedankt & Dziękuję Piotr Przybył @piotrprz @piotrprz.bsky.social Senior

    Developer Advocate Marit van Dijk @MaritvanDijk77 @maritvandijk.bsky.social Developer Advocate