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

Under the hoods: How Quarkus operates with GraalVM demonstrated with Neo4j

Under the hoods: How Quarkus operates with GraalVM demonstrated with Neo4j

Nearly 3 years since the inception many of us have seen amazing demos: How fast Quarkus based applications start, how helpful dev mode is, we have even learned continuous testing. And when going to production, it even works natively on GraalVM. This talk is the story that starts after a small meeting back in early 2019 in London that led to making the Neo4j driver compatible with GraalVM native over to providing a Quarkus extensions for just the connectivity and eventually ending with full support of Neo4j-ObjectGraphMapping framework in Quarkus. We will talk about the mechanisms Quarkus applies to create a closed world assumption that fulfills the needs of GraalVM native, how extensions need to deal with and the different modules being in a Quarkus extension. This talk will help you understanding why things in Quarkus work the way they do and how you can benefit from them. All of that will be demonstrated with Neo4j and the official Java connectivity to the worlds leading Graph database.

Michael Simons

November 09, 2022
Tweet

More Decks by Michael Simons

Other Decks in Programming

Transcript

  1. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    1
    Under the hoods:
    How Quarkus and others operate
    on GraalVM
    Michael Simons,
    Java Champion & Staff Software Engineer @ Neo4j
    Øredev 2022

    View Slide

  2. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Neo4j
    ● Graph database
    ● Custom wire protocol with drivers
    for a broad range of languages
    ● Web and CLI based shells,
    including visualization
    *and nice places like Aachen and Braunschweig and some others like London and San Mateo
    2
    MATCH (p:Product {name: 'Neo4j'}) -[:IS_CREATED_IN {with: '💙'}]->
    (c:City {name: 'Malmö(*)'})
    RETURN p, c
    View from Nordenskiöldsgatan

    View Slide

  3. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    © 2022 Neo4j, Inc. All rights reserved.
    3
    Why this talk?
    ● Frameworks do magic all the time (i.e. beans
    seems to be created from thin air and injected
    into the right place)
    ● Java allows access to all kind of things via
    magic incarnations
    ● Resources can be easily accessed
    ➡ Understanding what happens in a
    software becomes even more important as
    many things taken for granted do work
    differently in GraalVM.
    We want Neo4j to be excellent with GraalVM!
    “They say a little
    knowledge is a
    dangerous thing, but
    it's not one half so
    bad as a lot of
    ignorance.”
    - Terry Pratchett
    in “Equal Rites”

    View Slide

  4. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    4
    What is GraalVM?
    Native image, polyglot runtime, language
    framework or all of the before?
    4

    View Slide

  5. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    5
    GraalVM Architecture

    View Slide

  6. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    6
    All of it!
    import static java.lang.System.out;
    import org.graalvm.polyglot.*;
    public class HelloJS {
    public static void main(String... args) {
    var program = """
    const LocalDate = Java.type('java.time.LocalDate')
    let result = JSON.parse('{"greeting": "Hello, Øredev"}')
    result = { ...result, "when": LocalDate.now()}
    """;
    try (var context = Context.newBuilder().allowAllAccess(true).build()) {
    var result = context.eval(Source.create("js", program));
    out.println(
    result.getMember("greeting") + " on " + result.getMember("when")
    );
    }
    }
    }

    View Slide

  7. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Two execution modes
    ● JVM Runtime Mode
    When running programs on the HotSpot JVM, GraalVM defaults to the GraalVM
    compiler as the top-tier JIT compiler. At runtime, an application is loaded and
    executed normally on the JVM. The JVM passes bytecodes for Java or any
    other JVM-native language to the compiler, which compiles that to the machine
    code and returns it to the JVM.
    ● Native Image
    Native Image compiles Java code into a standalone native executable or a
    native shared library. The Java bytecode that is processed during the build of a
    native executable includes all application classes, dependencies, third party
    dependent libraries, and any JDK classes that are required.

    View Slide

  8. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    8
    Build-Time- and Runtime-Initialization
    ● Java semantics requires classes to be initialized at first access
    => Degrades performances, even hello world initializes a couple of
    hundred classes
    ○ Native image can push this to Build-Time, including static state
    ○ Used to be the default for nearly all classes
    ● Runtime-Initialization now the default, required classes must be
    enumerated still
    ○ JDK classes, including GC, are build-time initialized
    ○ So are “safe” classes
    ○ So are explicitly listed classes

    View Slide

  9. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    9
    Demo native image
    public class Hello {
    public static void main(String... a) {
    System.out.println("Hello, Øredev");
    }
    }

    View Slide

  10. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    10
    Not so fast…
    public class Hello2 {
    // native-image --no-fallback Hello2
    // java -agentlib:native-image-agent=config-output-dir=c Hello2.java
    // native-image -H:ReflectionConfigurationFiles=c/reflect-config.json Hello2
    public static void main(String... a) throws Exception {
    var method = Hello2.class
    .getDeclaredMethod(a.length == 0 ? "greeting1" : a[0]);
    System.out.println(method.invoke(null));
    }
    static String greeting1() {
    return "Hello, Øredev";
    }
    static String greeting2() {
    return "God morgon, Øredev";
    }
    }

    View Slide

  11. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    11
    What is Quarkus?
    11

    View Slide

  12. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Quarkus
    ● First appearance 2019
    ● Java framework tailored for deployment on Kubernetes.
    ○ Hotspot and GraalVM on par
    ● Container first
    ● unified configuration
    ● "Batteries included" approach
    ○ Live coding: Quick turnaround
    ○ Dev mode
    ○ Dev containers / (bast on Testcontainers)
    ● Fast startup, low memory

    View Slide

  13. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    13
    All-in towards build-time initialization
    ● Configuration
    ● (CDI-Lite) Beans
    ● Resources
    ● Entities
    Done for both JVM mode and Native mode!!!
    Building a lot of synthetic byte code

    View Slide

  14. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Goals Challenges for (Neo4j) connectivity
    ● Creating persistent TCP connections
    ● Discover classes (aka Entities) for OGM
    ● Evaluate unified configurations
    ● Discover or enumerate needed resources
    ● Bossfight SSL

    View Slide

  15. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Create a closed world
    15
    Or at least, assume one.
    15

    View Slide

  16. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Different solutions
    ● Annotation processing (javax.annotation.processing.*)
    ● Programmatically (Explicit)
    ● Functional extension points / Hints
    (More for the developers building on frameworks and libraries)

    View Slide

  17. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Quarkus
    ● Programmatically for providers of extensions
    ● Hints (Annotationen) for end users and direct access to native-image
    related tools

    View Slide

  18. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Structure and flow of a Quarkus-Extension
    Augmentation
    Static Init Runtime Init

    View Slide

  19. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    19
    Demo time
    (Break all the things)
    19

    View Slide

  20. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Going with the defaults
    ● GraalVM has defaulted to Runtime-initialization
    ● We followed that (move everything Built-Time to Quarkus) and than this

    View Slide

  21. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    The relevance to the ecosystem
    21
    (and Neo4j)
    21

    View Slide

  22. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    The relevance to the ecosystem
    ● GraalVM and Quarkus challenged a lot of assumptions
    ● Breath of fresh air, especially for Spring(!)
    ○ Spring going into a different direction here (Code instead of Bytecode
    generation)
    ● As a vendor, we want to not a single obstacle for our users to facilitate the
    driver in their native program

    View Slide

  23. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    Why?
    ● Faster startup times, less resource usage
    ○ (Startup times can be addressed by the CRaC (Coordinated Restore at
    Checkpoint) Project)
    ● Elasticity (scale to 0, scale up)
    ● Lambda
    ● Probably more secure
    ● Empowers Java to be used proper in CLI (together with PioCLI and
    others)

    View Slide

  24. © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    © 2022 Neo4j, Inc. All rights reserved.
    Michael Simons aka @rotnroll666 at Øredev 2022
    24
    Tack!
    Tooling around
    GraalVM
    Email [email protected]
    Twitter @rotnroll666
    Profile https://github.com/michael-simons
    Ramblings about
    Frameworks

    View Slide