Skip to content

Commit

Permalink
Blog post about the native compilation of application using virtual t…
Browse files Browse the repository at this point in the history
…hreads
  • Loading branch information
cescoffier committed Oct 17, 2023
1 parent 3ebdef7 commit d0a6467
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 1 deletion.
2 changes: 1 addition & 1 deletion _posts/2023-09-19-virtual-thread-1.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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_)
Expand Down
129 changes: 129 additions & 0 deletions _posts/2023-10-19-virtual-threads-5.adoc
Original file line number Diff line number Diff line change
@@ -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]
----
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
----

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!

0 comments on commit d0a6467

Please sign in to comment.