Guides

Getting started with Quarkus for Spring developers

As a Spring developer, you heard more and more about Quarkus: its pros and cons, its fast growth etc. So, you decided to adopt/try Quarkus for your (next) project(s) and wonder where to go next and where do you need to pay attention to when moving from Spring to Quarkus.

This guide tries to address exactly this concern. In the following, we will present you some main points you should be aware of when starting to develop with Quarkus, along with some useful sources.

  1. Quarkus is fairly a new Java toolkit. Thus, it is very well documented. It also provides a set of well-written technical guides that are a good starting point to get in touch and make the first steps with Quarkus. See here. It is an Open Source project licensed under the Apache License version 2.0. The source code is hosted in GitHub. If you have any question or concern, don’t hesitate to reach out to the Quarkus community.

  2. Same as Spring Initializr, you can go to code.quarkus.io to create a new application. Also, check out our Template Quarkus Guide to have our recommendations on certain topics.

  3. In Spring stack, we recommend structuring your application into multiple modules, known as our classic structure. Moving to Quarkus and the world of cloud-native, microservices where we build smaller applications compared to monoliths, we recommend keeping everything top-level and simple. Therefore, we propose the modern structure as a better fit.

  4. Quarkus focuses not only on delivering top features but also on the developer experience. The Quarkus’s Live Coding feature automatically detects changes made to Java files, application configuration, static resources or even classpath dependency changes and recompiles and redeploys the changes. As that, it solves the problem of traditional Java development workflow, hence improves productivity.

        Write Code → Compile → Deploy → Test Changes/ Refresh Browser/ etc → Repeat (traditional)
        Write Code → Test Changes/ Refresh Browser/ etc → Repeat (Quarkus)

    You can use this feature out of the box without any extra setup by running:

        mvn compile quarkus:dev

    Another highlight feature to speed up developing is the Quarkus’s Dev Mode with Dev Services, which can automatically provision unconfigured services in development and test mode. It means that if you include an extension and don’t configure it, Quarkus will automatically start the relevant service and wire up your application to use it, therefore will save you a lot of time setting up those services manually. In production mode, where the real configuration is provided, Dev Service will be disabled automatically.

    Also in Dev Mode, you can access the Dev UI at \q\dev to browse endpoints offered by various extensions, conceptually similar to what a Spring Boot actuator might provide.

  5. Quarkus is made of a small core on which relies hundreds of extensions. In fact, the power of Quarkus is its extension mechanism. Think of these extensions as your project dependencies. You can add it per dependency manager such as maven or gradle.

    mvn quarkus:list-extensions
    mvn quarkus:add-extension -Dextensions="groupId:artifactId"
    (or add it manually to pom.xml)
    # or
    gradle list-extensions
    (add dependency to build.gradle)

    Like Spring Boot, Quarkus also has a vast ecosystem of extensions with commonly-used technologies.

    Table 44. Example of common Quarkus extensions and the Spring Boot Starters with similar functionality (book: Quarkus for Spring Developer)
    Quarkus extension Spring Boot Starter

    quarkus-resteasy-jackson

    spring-boot-starter-web

    spring-boot-starter-webflux

    quarkus-resteasy-reactive-jackson

    spring-boot-starter-web

    spring-boot-starter-webflux

    quarkus-hibernate-orm-panache

    spring-boot-starter-data-jpa

    quarkus-hibernate-orm-rest-datapanache

    spring-boot-starter-data-rest

    quarkus-hibernate-reactive-panache

    spring-boot-starter-data-r2dbc

    quarkus-mongodb-panache

    spring-boot-starter-data-mongodb

    spring-boot-starter-data-mongodb-reactive

    quarkus-hibernate-validator

    spring-boot-starter-validation

    quarkus-qpid-jms

    spring-boot-starter-activemq

    quarkus-artemis-jms

    spring-boot-starter-artemis

    quarkus-cache

    spring-boot-starter-cache

    quarkus-redis-client

    spring-boot-starter-data-redis

    spring-boot-starter-data-redis-reactive

    quarkus-mailer

    spring-boot-starter-mail

    quarkus-quartz

    spring-boot-starter-quartz

    quarkus-oidc

    spring-boot-starter-oauth2-resource-server

    quarkus-oidc-client

    spring-boot-starter-oauth2-client

    quarkus-smallrye-jwt

    spring-boot-starter-security

    A full list of all Quarkus extensions can be found here. Furthermore, you can check out the community extensions hosted by Quarkiverse Hub. Quarkus has some extensions for Spring API as well which is helpful while migrating from Spring to Quarkus.

    Besides extensions, which are officially maintained by Quarkus team, Quarkus allows adding external libraries too. While extensions can be integrated seamlessly into Quarkus as they can be processed at build time and be built in native mode with GraalVM, external dependencies might not work out of the box with native compilation. If that is the case, then you have to recompile them with the right GraalVM configuration to make them work.

  6. Quarkus’s design accounted for native compilation by default. A Quarkus native executable starts much faster and utilizes far less memory than a traditional JVM. To get familiar with building native executable, configuring and running it, please check out our Native Image Guide. Be sure to test your code in both JVM and native mode.

  7. Both Quarkus and Spring include testing frameworks based on JUnit and Mockito. Thus, by design, Quarkus enables test-driven development by detecting affected tests as changes are made and automatically rerun them in background. As that, it gives developer instant feedback, hence improves productivity. To use continuous testing, execute the following command:

    mvn quarkus:dev
  8. For the sake of performance optimization, Quarkus avoids reflection as much as possible, instead favoring static class binding. When building a native executable, it analyzes the call tree and removes all the classes/methods/fields that are not used directly. As a consequence, the elements used via reflection are not part of the call tree so they are dead code eliminated (if not called directly in other cases).

    A common example is the JSON libraries which typically use reflection to serialize the objects to JSON. If you use them out of the box, you might encounter some errors in native mode. So, be sure to register the elements for reflection explicitly. A How-to is provided by Quarkus Registering For Reflection with practical program snippets.

A very good read on the topic is the e-book Quarkus for Spring Developers by Red Hat. Another good source for direct hands-on coding tutorial is Katacoda Quarkus for Spring Boot Developers

Configuration

External Application Configuration
Database Configuration

In Quarkus, Hibernate is provided by the quarkus-hibernate-orm extension. Ensure the extension is added to your pom.xml as follows:

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-hibernate-orm</artifactId>
</dependency>

You additionally have to add the respective JDBC driver extension to your pom.xml. There are different drivers for different database types. See Quarkus Hibernate guide.

Database System and Access

You need to configure which database type you want to use, as well as the location and credentials to access it. The defaults are configured in application.properties. The file should therefore contain the properties as in the given example:

  quarkus.datasource.jdbc.url=jdbc:postgresql://database.enterprise.com/app
  quarkus.datasource.username=appuser01
  quarkus.datasource.password=************
  quarkus.datasource.db-kind=postgresql

  # drop and create the database at startup (use only for local development)
  quarkus.hibernate-orm.database.generation=drop-and-create
Database Logging

Add the following properties to application.properties to enable logging of database queries for debugging purposes.

quarkus.hibernate-orm.log.sql=true
quarkus.hibernate-orm.log.format-sql=true

#Logs SQL bind parameters. Setting it to true is obviously not recommended in production.
quarkus.hibernate-orm.log.bind-parameters=true

CORS support

When you are developing Javascript client and server application separately, you have to deal with cross domain issues. We have to request from a origin domain distinct to target domain and browser does not allow this.

So , we need to prepare server side to accept request from other domains. We need to cover the following points:

  • Accept request from other domains.

  • Accept devonfw used headers like X-CSRF-TOKEN or correlationId.

  • Be prepared to receive secured request (cookies).

It is important to note that if you are using security in your request (sending cookies) you have to set withCredentials flag to true in your client side request and deal with special IE8 characteristics.

Configuring CORS support

Quarkus comes with a CORS filter which implements the javax.servlet.Filter interface and intercepts all incoming HTTP requests. It can be enabled in the Quarkus configuration file, src/main/resources/application.properties:

quarkus.http.cors=true
Configuration with quarkus

Here’s an example of a full CORS filter configuration, including a regular expression defining an allowed origin:

# enable cors filter
quarkus.http.cors=true
# configurations cors
quarkus.http.cors.origins=http://foo.com,http://www.bar.io,/https://([a-z0-9\\-_]+)\\.app\\.mydomain\\.com/
quarkus.http.cors.methods=OPTIONS,HEAD,GET,PUT,POST,DELETE,PATCH
quarkus.http.cors.headers=X-Custom
quarkus.http.cors.exposed-headers=Content-Disposition
quarkus.http.cors.access-control-max-age=24H
quarkus.http.cors.access-control-allow-credentials=true
Attribute Default Description HTTP Header

quarkus.http.cors.access-control-allow-credentials

-

Boolean value to tell the browsers to expose the response to front-end JavaScript code when the request’s credentials mode Request.credentials is “include”

Access-Control-Allow-Credentials

quarkus.http.cors.origins

*

The comma-separated list of origins allowed for CORS. Values starting and ending with '/'' will be treated as regular expressions. The filter allows any origin if this is not set or set to '*'.

Access-Control-Allow-Origin

quarkus.http.cors.methods

*

The comma-separated list of HTTP methods allowed for CORS. The filter allows any method if this is not set or set to '*'.

Access-Control-Allow-Methods

quarkus.http.cors.headers

*

The comma-separated list of HTTP headers allowed for CORS. The filter allows any header if this is not set or set to '*'.

Access-Control-Allow-Headers

quarkus.http.cors.exposed-headers

*

The comma-separated list of HTTP headers exposed in CORS. The filter allows any headers to be exposed if this is not set or set to '*'.

Access-Control-Expose-Headers

quarkus.http.cors.access-control-max-age

-

The duration (see note below) indicating how long the results of a pre-flight request can be cached.

Access-Control-Max-Age

Configuration with service mesh

Alternatively, if you use service mesh, you can also define your CORS policy directly there. Here is an example from istio

More information about the CORS headers can be found here

Quarkus template

Quarkus Code Generator is providing a lot of alternatives on technologies and libraries to be integrated. Detailed guides to multiple topics can be found here.

Thus, the large selection can be difficult for developer to get started. Therefore, in this guide, we aims to provide a general suggestion on basic frameworks, libraries, technologies to make it easy for developer to begin with.

With that said, please take this as a recommendation and not a compulsion. Depend on your project requirements, you might have to use another stack in comparison to what is listed below.

If you are new to Quarkus, consider checking out their getting started guide to have an overview about how to create, run, test as well as package a Quarkus application. Another recommended source to get started is the Katacoda tutorials.

Basic templates
  1. simple REST API (go to code.quarkus.io)

  2. simple REST API with monitoring (go to code.quarkus.io)

Table 45. Topic-based suggested implementation
Topic Detail Suggested implementation Note

runtime

servlet-container

Undertow

component management

dependency injection

ArC

ArC is based on JSR 365. It also provides interceptors that can be used to implement the same functionality as AOP provides

configuration

SmallRye Config

SmallRye Config is an implementation of Eclipse MicroProfile Config. It also supports YAML configuration files

persistence

OR-mapper

Hibernate ORM, Spring Data JPA

Hibernate ORM is the de facto standard JPA implementation and works perfectly in Quarkus. Quarkus also provides a compatibility layer for Spring Data JPA repositories in the form of the spring-data-jpa extension.

batch

Quarkus JBeret Extension is a non-official extension, which is hosted in the Quarkiverse Hub. It is an implementation of JSR 352.

service

REST services

RESTEasy

RESTEasy is an portable implementation of the new JCP specification JAX-RS JSR-311. It can be documented via Swagger OpenAPI.

async messaging

SmallRye Reactive Messaging, Vert.x EventBus

SmallRye Reactive Messaging is an implementation of the Eclipse MicroProfile Reactive Messaging specification 1.0. You can also utilize SmallRye Reactive Messaging in your Quarkus application to interact with Apache Kafka.

marshalling

RESTEasy Jackson, RESTEasy JSON-B, RESTEasy JAXB, RESTEasy Multipart

cloud

kubernetes

Kubernetes

deployment

Minikube, k3d

Minikube is quite popular when a Kubernetes cluster is needed for development purposes. Quarkus supports this with the quarkus-minikube extension.

logging

framework

JBoss Log Manager and the JBoss Logging facade

Internally, Quarkus uses JBoss Log Manager and the JBoss Logging facade. Logs from other supported Logging API (JBoss Logging, SLF4J, Apache Commons Logging) will be merged.

validation

framework

Hibernate Validator/Bean Validation (JSR 380)

security

authentication & authorization

JWT authentication

Quarkus supports various security mechanisms. Depending on your protocol, identity provider you can choose the necessary extensions such as quarkus-oidc quarkus-smallrye-jwt quarkus-elytron-security-oauth2.

monitoring

framework

Micrometer Metrics, SmallRye Metrics

SmallRye Metrics is an implementation of the MicroProfile Metrics specification. Quarkus also offers various extensions to customize the metrics.

health

SmallRye Health

SmallRye Health is an implementation of the MicroProfile Health specification.

fault tolerance

SmallRye Fault Tolerance

SmallRye Fault Tolerance is an implementation of the MicroProfile Fault Tolerance specification.

Building a native image

Quarkus provides the ability to create a native executable of the application called native image. Unlike other Java based deployments such native image will only run on the architecture and operating system it is compiled for. Also, no JVM is needed to run the native-image. This improves the startup time, performance and efficiency. A distribution of GraalVM is needed. You can find the differences between the available distributions here.

To build your quarkus app as native-image you have two options that are descibed in the following sections.

Build a native executable with GraalVM

To build a Quarkus application you can install GraalVM locally on your machine as described below. Therefore read the basic Quarkus application chapter, or clone the example project provided by devonfw. Follow this chapter from the Quarkus Guide for building a native executable.

Installing GraalVM

A native image can be created locally or through a container environment. To create a native image locally an installed and configured version of GraalVM is needed, you can follow the installation guide from Quarkus or the guide provided by GraalVM for this.

Build a native executable with GraalVM through container environment

In order to make the build of native images more portable, you can also use your container environment and run the GraalVM inside a container (typically Docker). You can simply install Docker with your devonfw-ide distribution just follow this description Docker with devonfw-ide. Follow this chapter to build a native Linux image through container runtime.

Configuring the native executable

A list of all configuration properties for a native image can be found here.

Last updated 2021-10-21 17:17:16 UTC