From d0a64679c36a9931f11707ad4f7142aac4e16c38 Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Tue, 17 Oct 2023 10:17:37 +0200 Subject: [PATCH] Blog post about the native compilation of application using virtual threads --- _posts/2023-09-19-virtual-thread-1.adoc | 2 +- _posts/2023-10-19-virtual-threads-5.adoc | 129 +++++++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 _posts/2023-10-19-virtual-threads-5.adoc diff --git a/_posts/2023-09-19-virtual-thread-1.adoc b/_posts/2023-09-19-virtual-thread-1.adoc index 17b812131f..b8008b487d 100644 --- a/_posts/2023-09-19-virtual-thread-1.adoc +++ b/_posts/2023-09-19-virtual-thread-1.adoc @@ -358,7 +358,7 @@ Next, we will cover: - https://quarkus.io/blog/virtual-threads-2/[How to write a crud application using virtual threads] - https://quarkus.io/blog/virtual-threads-3/[How to test virtual threads applications] - https://quarkus.io/blog/virtual-threads-4/[How to process Kafka messages using virtual threads] -- How to build a native executable when using virtual threads (_to be published_) +- https://quarkus.io/blog/virtual-threads-5/[How to build a native executable when using virtual threads] - How to containerize an application using virtual threads (in JVM mode) (_to be published_) - How to containerize an application using virtual threads in native mode (_to be published_) - How to process Kafka messages using virtual threads (_to be published_) diff --git a/_posts/2023-10-19-virtual-threads-5.adoc b/_posts/2023-10-19-virtual-threads-5.adoc new file mode 100644 index 0000000000..1835483abb --- /dev/null +++ b/_posts/2023-10-19-virtual-threads-5.adoc @@ -0,0 +1,129 @@ +--- +layout: post +title: 'Compiling virtual thread applications into native executables' +date: 2023-10-19 +tags: virtual-threads native +synopsis: 'Learn how to compile applications using virtual threads into native executable.' +author: cescoffier +--- +:imagesdir: /assets/images/posts/virtual-threads + +In https://quarkus.io/blog/virtual-threads-2/[another blog post], we have seen how you can implement a CRUD application with Quarkus to utilize virtual threads. +This post will show how you can compile such an application into a native executable. + +== Installing GraalVM 21 + +To compile a Quarkus application leveraging virtual threads into a native executable, you need a GraalVM version supporting Java 21. +You can download it from https://github.com/graalvm/graalvm-ce-builds/releases/tag/jdk-21.0.0[GitHub]. + +Alternatively, you can use the https://sdkman.io/[SDKMAN] tool to install it: + +[source, bash] +---- +> sdk install java 21-graalce +Downloading: java 21-graalce + +In progress... + +Repackaging Java 21-graalce... + +Done repackaging... +Cleaning up residual files... + +Installing: java 21-graalce +Done installing! + +Do you want java 21-graalce to be set as default? (Y/n): n +---- + +Once installed, make sure the `GRAALVM_HOME` environment variable points to the GraalVM installation directory: + +[source, bash] +---- +> export GRAALVM_HOME=$HOME/.sdkman/candidates/java/21-graalce +---- + +== Compiling the application into a native executable + +We will reuse the CRUD application developed in a https://quarkus.io/blog/virtual-threads-2/[previous blog post]. +The source code is located in the https://github.com/quarkusio/virtual-threads-demos/tree/main/crud-example[virtual-threads-demos GitHub repository]. +Note that while we are using the CRUD application, the same approach can be used with any Quarkus application leveraging virtual threads, including the other demos from the repository. + +First make sure you use Java 21+ and that the `GRAALVM_HOME` environment variable points to the GraalVM installation directory. + +Then, in the `pom.xml` file, add the `native` profile: + +[source, xml] +---- + + + native + + + native + + + + native + + + +---- + +The `native` profile is activated when the `native` property is set. +So, compile the application with: + +[source, bash] +---- +> mvn clean package -Dnative +---- + +The compilation takes a few minutes. +Once done, you can run the application: + +* 1) First, start the database: + +[source, bash] +---- +> docker run --ulimit memlock=-1:-1 -d -it --rm=true --memory-swappiness=0 \ + --name postgres-quarkus-demo -e POSTGRES_USER=restcrud \ + -e POSTGRES_PASSWORD=restcrud -e POSTGRES_DB=rest-crud \ + -p 5432:5432 postgres:15-bullseye +---- + +* 2) Then, start the application: + +[source, bash] +---- +> ./target/crud-example-1.0.0-SNAPSHOT-runner +---- + +You get: + +[source, bash] +---- +> ./target/crud-example-1.0.0-SNAPSHOT-runner +__ ____ __ _____ ___ __ ____ ______ + --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ + -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ +--\___\_\____/_/ |_/_/|_/_/|_|\____/___/ +2023-10-17 09:44:34,925 INFO [io.quarkus] (main) crud-example 1.0.0-SNAPSHOT native (powered by Quarkus 3.4.1) started in 0.072s. Listening on: http://0.0.0.0:8080 +2023-10-17 09:44:34,925 INFO [io.quarkus] (main) Profile prod activated. +2023-10-17 09:44:34,925 INFO [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, hibernate-orm-panache, hibernate-validator, jdbc-postgresql, narayana-jta, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, vertx] +---- + +Then, open the application in a browser (http://localhost:8080) and start adding, updating, and completing tasks. +You will see in the logs that the processing of these requests are executed on virtual threads: + +[source, text] +---- +2023-10-17 10:15:09,992 INFO [org.acm.cru.TodoResource] (quarkus-virtual-thread-0) Called on VirtualThread[#78,quarkus-virtual-thread-0]/runnable@ForkJoinPool-5-worker-1 +2023-10-17 10:15:13,136 INFO [org.acm.cru.TodoResource] (quarkus-virtual-thread-1) Called on VirtualThread[#85,quarkus-virtual-thread-1]/runnable@ForkJoinPool-5-worker-1 +---- + +== Summary + +This blog post explains how to compile a Quarkus application leveraging virtual threads into a native executable. +First, make sure that you have a GraalVM installation supporting Java 21+. +Then, add the `native` profile to the `pom.xml` file and compile the application using the `-Dnative` option. +Finally, run it as any other native executable!