Gradle + Quarkus Hello World example
This article shows how to create or scaffold a Gradle + Quarkus JAX-RS hello world project, which creates a /hello
endpoint and returns a string.
Technologies used:
- Quarkus 1.11.0
- Gradle 6.7
- Maven 3.6.3
- Java 11
Topics
- Creating a new Gradle + Quartus project
- Gradle + Quarkus Project Structure
- Quarkus and build.gradle
- Quarkus Dependencies (runtimeClasspath)
- Quarkus JAX-RX endpoint
- Quarkus and Dockerfile
- Gradle run Quarkus in Dev Mode
- Download Source Code
- References
1. Creating a new Gradle + Quartus project
We use the Maven plugin quarkus-maven-plugin and specified an extra option -DbuildTool=gradle
to create or scaffold a Gradle + Quarkus project.
1.1 The below command will create a simple Quarkus JAX-RX project.
For Linux and macOS system.
mvn io.quarkus:quarkus-maven-plugin:1.11.0.Final:create \
-DprojectGroupId=com.mkyong \
-DprojectArtifactId=quarkus-hello-world-gradle \
-DclassName="com.mkyong.quarkus.HelloResource" \
-Dpath="/hello" \
-DbuildTool=gradle
For Windows, cmd
or command prompt, replace the new line \
with a ^
.
mvn io.quarkus:quarkus-maven-plugin:1.11.0.Final:create ^
-DprojectGroupId=com.mkyong ^
-DprojectArtifactId=quarkus-hello-world-gradle ^
-DclassName="com.mkyong.quarkus.HelloResource" ^
-Dpath="/hello" ^
-DbuildTool=gradle
Output
> mvn io.quarkus:quarkus-maven-plugin:1.11.0.Final:create ^
More? -DprojectGroupId=com.mkyong ^
More? -DprojectArtifactId=quarkus-hello-world-gradle ^
More? -DclassName="com.mkyong.quarkus.HelloResource" ^
More? -Dpath="/hello" ^
More? -DbuildTool=gradle
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- quarkus-maven-plugin:1.11.0.Final:create (default-cli) @ standalone-pom ---
-----------
applying codestarts...
? java
? gradle
? quarkus
? config-properties
? dockerfiles
? gradle-wrapper
? resteasy-example
-----------
? quarkus project has been successfully generated in:
--> C:\Users\mkyong\projects\quarkus\quarkus-hello-world-gradle
-----------
[INFO]
[INFO] ========================================================================================
[INFO] Your new application has been created in C:\Users\mkyong\projects\quarkus\quarkus-hello-world-gradle
[INFO] Navigate into this directory and launch your application with mvn quarkus:dev
[INFO] Your application will be accessible on http://localhost:8080
[INFO] ========================================================================================
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.095 s
[INFO] Finished at: 2021-01-27T14:32:13+08:00
[INFO] ------------------------------------------------------------------------
2. Gradle + Quarkus Project Structure
The above command created a new project named quarkus-hello-world-gradle
, and generates the following files and directories:
- Standard Maven directory structure.
- Gradle
build.gradle
and related wrapper. HelloResource.java
for/hello
endpoint.- Unit Tests.
- A landing page
resources\META-INF\resources\index.html
forhttp://localhost:8080
Dockerfile
files, forjvm
ornative
mode.- The application configuration file,
application.properties
.
> cd quarkus-hello-world-gradle
> tree /F
Folder PATH listing
Volume serial number is A446-18E6
C:.
│ .dockerignore
│ .gitignore
│ build.gradle
│ gradle.properties
│ gradlew
│ gradlew.bat
│ README.md
│ settings.gradle
│
├───gradle
│ └───wrapper
│ gradle-wrapper.jar
│ gradle-wrapper.properties
│
└───src
├───main
│ ├───docker
│ │ Dockerfile.fast-jar
│ │ Dockerfile.jvm
│ │ Dockerfile.native
│ │
│ ├───java
│ │ └───com
│ │ └───mkyong
│ │ └───quarkus
│ │ HelloResource.java
│ │
│ └───resources
│ │ application.properties
│ │
│ └───META-INF
│ └───resources
│ index.html
│
├───native-test
│ └───java
│ └───com
│ └───mkyong
│ └───quarkus
│ NativeHelloResourceIT.java
│
└───test
└───java
└───com
└───mkyong
└───quarkus
HelloResourceTest.java
3. Quarkus and build.gradle
Review the Gradle related files: build.gradle
, gradle.properties
and settings.gradle
.
3.1 The project required quarkus-arc
for dependency injection; and quarkus-resteasy
for JAX-RS endpoint.
plugins {
id 'java'
id 'io.quarkus'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-arc'
implementation 'io.quarkus:quarkus-resteasy'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
}
group 'com.mkyong'
version '1.0.0-SNAPSHOT'
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
compileJava {
options.encoding = 'UTF-8'
options.compilerArgs << '-parameters'
}
compileTestJava {
options.encoding = 'UTF-8'
}
3.2 Project properties like Quarkus package and version.
#Gradle properties
quarkusPluginId=io.quarkus
quarkusPluginVersion=1.11.0.Final
quarkusPlatformGroupId=io.quarkus
quarkusPlatformArtifactId=quarkus-universe-bom
quarkusPlatformVersion=1.11.0.Final
org.gradle.logging.level=INFO
3.3 Project name and plugin info.
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
}
plugins {
id "${quarkusPluginId}" version "${quarkusPluginVersion}"
}
}
rootProject.name='quarkus-hello-world-gradle'
4. Quarkus Dependencies (runtimeClasspath)
In Gradle, we can use gradle dependencies --configuration runtimeClasspath
to show only the runtime classpath.
Other --configuration
options
compileClasspath
runtimeClasspath
testCompileClasspath
testCompileClasspath
nativeTestCompileClasspath
nativeTestRuntimeClasspath
4.1 For a standard Quarkus JAX-RX project, it reuses a lot of proven technologies.
The Quarkus core Technologies:
- Quarkus uses Vert.x and Netty at its core, providing reactive and non-blocking HTTP layer.
- Quarkus uses RESTEasy for the JAX-RS endpoint.
- Quarkus uses ArC as the dependency injection solution.
- Quarkus uses JBoss Log Manager as the default logging framework.
- Quartus uses a modified version of Undertow (Servlet/Websocket engine) that runs on top of Vert.x
- Quarkus uses SmallRye Config, implementation of Eclipse MicroProfile Config, for configuration data.
> gradle dependencies --configuration runtimeClasspath
------------------------------------------------------------
Root project
------------------------------------------------------------
runtimeClasspath - Runtime classpath of source set 'main'.
+--- io.quarkus:quarkus-universe-bom:1.11.0.Final
| +--- io.quarkus:quarkus-arc:1.11.0.Final (c)
| +--- io.quarkus:quarkus-resteasy:1.11.0.Final (c)
| +--- io.quarkus.arc:arc:1.11.0.Final (c)
| +--- io.quarkus:quarkus-core:1.11.0.Final (c)
| +--- org.eclipse.microprofile.context-propagation:microprofile-context-propagation-api:1.0.1 (c)
| +--- io.quarkus:quarkus-vertx-http:1.11.0.Final (c)
| +--- io.quarkus:quarkus-resteasy-server-common:1.11.0.Final (c)
| +--- jakarta.enterprise:jakarta.enterprise.cdi-api:2.0.2 (c)
| +--- jakarta.annotation:jakarta.annotation-api:1.3.5 (c)
| +--- jakarta.transaction:jakarta.transaction-api:1.3.3 (c)
| +--- org.jboss.logging:jboss-logging:3.4.1.Final (c)
| +--- jakarta.inject:jakarta.inject-api:1.0 (c)
| +--- io.quarkus:quarkus-ide-launcher:1.11.0.Final (c)
| +--- io.quarkus:quarkus-development-mode-spi:1.11.0.Final (c)
| +--- io.smallrye.config:smallrye-config:1.10.0 (c)
| +--- org.jboss.logmanager:jboss-logmanager-embedded:1.0.6 (c)
| +--- org.jboss.logging:jboss-logging-annotations:2.2.0.Final (c)
| +--- org.jboss.threads:jboss-threads:3.2.0.Final (c)
| +--- org.slf4j:slf4j-api:1.7.30 (c)
| +--- org.jboss.slf4j:slf4j-jboss-logmanager:1.1.0.Final (c)
| +--- org.graalvm.sdk:graal-sdk:20.3.0 (c)
| +--- org.wildfly.common:wildfly-common:1.5.4.Final-format-001 (c)
| +--- io.quarkus:quarkus-bootstrap-runner:1.11.0.Final (c)
| +--- io.quarkus:quarkus-security-runtime-spi:1.11.0.Final (c)
| +--- io.quarkus:quarkus-vertx-http-dev-console-runtime-spi:1.11.0.Final (c)
| +--- io.quarkus.security:quarkus-security:1.1.3.Final (c)
| +--- io.quarkus:quarkus-vertx-core:1.11.0.Final (c)
| +--- io.vertx:vertx-web:3.9.5 (c)
| +--- io.quarkus:quarkus-resteasy-common:1.11.0.Final (c)
| +--- jakarta.validation:jakarta.validation-api:2.0.2 (c)
| +--- jakarta.interceptor:jakarta.interceptor-api:1.2.5 (c)
| +--- io.smallrye.common:smallrye-common-annotation:1.5.0 (c)
| +--- io.smallrye.config:smallrye-config-common:1.10.0 (c)
| +--- io.smallrye.common:smallrye-common-expression:1.5.0 (c)
| +--- io.smallrye.common:smallrye-common-constraint:1.5.0 (c)
| +--- io.smallrye.common:smallrye-common-classloader:1.5.0 (c)
| +--- io.smallrye.common:smallrye-common-io:1.5.0 (c)
| +--- io.smallrye.reactive:mutiny:0.12.5 (c)
| +--- io.quarkus:quarkus-netty:1.11.0.Final (c)
| +--- io.vertx:vertx-core:3.9.5 (c)
| +--- io.vertx:vertx-web-common:3.9.5 (c)
| +--- io.vertx:vertx-auth-common:3.9.5 (c)
| +--- io.vertx:vertx-bridge-common:3.9.5 (c)
| +--- org.jboss.resteasy:resteasy-core:4.5.8.SP1 (c)
| +--- com.sun.activation:jakarta.activation:1.2.1 (c)
| +--- org.eclipse.microprofile.config:microprofile-config-api:1.4 (c)
| +--- io.smallrye.common:smallrye-common-function:1.5.0 (c)
| +--- org.reactivestreams:reactive-streams:1.0.3 (c)
| +--- io.netty:netty-codec:4.1.49.Final (c)
| +--- io.netty:netty-handler:4.1.49.Final (c)
| +--- io.netty:netty-common:4.1.49.Final (c)
| +--- io.netty:netty-buffer:4.1.49.Final (c)
| +--- io.netty:netty-transport:4.1.49.Final (c)
| +--- io.netty:netty-handler-proxy:4.1.49.Final (c)
| +--- io.netty:netty-codec-http:4.1.49.Final (c)
| +--- io.netty:netty-codec-http2:4.1.49.Final (c)
| +--- io.netty:netty-resolver:4.1.49.Final (c)
| +--- io.netty:netty-resolver-dns:4.1.49.Final (c)
| +--- com.fasterxml.jackson.core:jackson-core:2.11.3 (c)
| +--- com.fasterxml.jackson.core:jackson-databind:2.11.3 (c)
| +--- org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.1_spec:2.0.1.Final (c)
| +--- org.jboss.spec.javax.xml.bind:jboss-jaxb-api_2.3_spec:2.0.0.Final (c)
| +--- org.jboss.resteasy:resteasy-core-spi:4.5.8.SP1 (c)
| +--- io.netty:netty-codec-socks:4.1.49.Final (c)
| +--- io.netty:netty-codec-dns:4.1.49.Final (c)
| \--- com.fasterxml.jackson.core:jackson-annotations:2.11.3 (c)
+--- io.quarkus:quarkus-arc -> 1.11.0.Final
| +--- io.quarkus.arc:arc:1.11.0.Final
| | +--- jakarta.enterprise:jakarta.enterprise.cdi-api:2.0.2
| | | +--- jakarta.el:jakarta.el-api:3.0.3
| | | +--- jakarta.interceptor:jakarta.interceptor-api:1.2.5
| | | | \--- jakarta.annotation:jakarta.annotation-api:1.3.5
| | | \--- jakarta.inject:jakarta.inject-api:1.0
| | +--- jakarta.annotation:jakarta.annotation-api:1.3.5
| | +--- jakarta.transaction:jakarta.transaction-api:1.3.3
| | \--- org.jboss.logging:jboss-logging:3.3.2.Final -> 3.4.1.Final
| +--- io.quarkus:quarkus-core:1.11.0.Final
| | +--- jakarta.annotation:jakarta.annotation-api:1.3.5
| | +--- jakarta.enterprise:jakarta.enterprise.cdi-api:2.0.2 (*)
| | +--- jakarta.inject:jakarta.inject-api:1.0
| | +--- io.quarkus:quarkus-ide-launcher:1.11.0.Final
| | +--- io.quarkus:quarkus-development-mode-spi:1.11.0.Final
| | +--- io.smallrye.config:smallrye-config:1.10.0
| | | +--- io.smallrye.common:smallrye-common-annotation:1.5.0
| | | +--- io.smallrye.config:smallrye-config-common:1.10.0
| | | | +--- org.eclipse.microprofile.config:microprofile-config-api:1.4
| | | | +--- io.smallrye.common:smallrye-common-classloader:1.5.0
| | | | \--- org.jboss.logging:jboss-logging:3.4.1.Final
| | | +--- io.smallrye.common:smallrye-common-expression:1.5.0
| | | | +--- io.smallrye.common:smallrye-common-function:1.5.0
| | | | | \--- io.smallrye.common:smallrye-common-constraint:1.5.0
| | | | | \--- org.jboss.logging:jboss-logging:3.4.1.Final
| | | | \--- org.jboss.logging:jboss-logging:3.4.1.Final
| | | +--- io.smallrye.common:smallrye-common-constraint:1.5.0 (*)
| | | +--- io.smallrye.common:smallrye-common-classloader:1.5.0
| | | \--- org.jboss.logging:jboss-logging:3.4.1.Final
| | +--- org.jboss.logging:jboss-logging:3.4.1.Final
| | +--- org.jboss.logmanager:jboss-logmanager-embedded:1.0.6
| | | \--- org.wildfly.common:wildfly-common:1.5.0.Final-format-001 -> 1.5.4.Final-format-001
| | +--- org.jboss.logging:jboss-logging-annotations:2.2.0.Final
| | +--- org.jboss.threads:jboss-threads:3.2.0.Final
| | | +--- org.jboss.logging:jboss-logging:3.4.1.Final
| | | \--- org.wildfly.common:wildfly-common:1.5.0.Final -> 1.5.4.Final-format-001
| | +--- org.slf4j:slf4j-api:1.7.30
| | +--- org.jboss.slf4j:slf4j-jboss-logmanager:1.1.0.Final
| | +--- org.graalvm.sdk:graal-sdk:20.3.0
| | +--- org.wildfly.common:wildfly-common:1.5.4.Final-format-001
| | \--- io.quarkus:quarkus-bootstrap-runner:1.11.0.Final
| | +--- io.smallrye.common:smallrye-common-io:1.5.0
| | +--- org.jboss.logmanager:jboss-logmanager-embedded:1.0.5 -> 1.0.6 (*)
| | \--- org.jboss.logging:jboss-logging:3.3.2.Final -> 3.4.1.Final
| \--- org.eclipse.microprofile.context-propagation:microprofile-context-propagation-api:1.0.1
\--- io.quarkus:quarkus-resteasy -> 1.11.0.Final
+--- io.quarkus:quarkus-vertx-http:1.11.0.Final
| +--- io.quarkus:quarkus-core:1.11.0.Final (*)
| +--- io.quarkus:quarkus-security-runtime-spi:1.11.0.Final
| | \--- io.quarkus:quarkus-core:1.11.0.Final (*)
| +--- io.quarkus:quarkus-vertx-http-dev-console-runtime-spi:1.11.0.Final
| | +--- io.quarkus:quarkus-core:1.11.0.Final (*)
| | +--- io.quarkus.arc:arc:1.11.0.Final (*)
| | \--- io.vertx:vertx-web:3.9.5
| | +--- io.vertx:vertx-web-common:3.9.5
| | | \--- io.vertx:vertx-core:3.9.5
| | | +--- io.netty:netty-common:4.1.49.Final
| | | +--- io.netty:netty-buffer:4.1.49.Final
| | | | \--- io.netty:netty-common:4.1.49.Final
| | | +--- io.netty:netty-transport:4.1.49.Final
| | | | +--- io.netty:netty-common:4.1.49.Final
| | | | +--- io.netty:netty-buffer:4.1.49.Final (*)
| | | | \--- io.netty:netty-resolver:4.1.49.Final
| | | | \--- io.netty:netty-common:4.1.49.Final
| | | +--- io.netty:netty-handler:4.1.49.Final
| | | | +--- io.netty:netty-common:4.1.49.Final
| | | | +--- io.netty:netty-resolver:4.1.49.Final (*)
| | | | +--- io.netty:netty-buffer:4.1.49.Final (*)
| | | | +--- io.netty:netty-transport:4.1.49.Final (*)
| | | | \--- io.netty:netty-codec:4.1.49.Final
| | | | +--- io.netty:netty-common:4.1.49.Final
| | | | +--- io.netty:netty-buffer:4.1.49.Final (*)
| | | | \--- io.netty:netty-transport:4.1.49.Final (*)
| | | +--- io.netty:netty-handler-proxy:4.1.49.Final
| | | | +--- io.netty:netty-common:4.1.49.Final
| | | | +--- io.netty:netty-buffer:4.1.49.Final (*)
| | | | +--- io.netty:netty-transport:4.1.49.Final (*)
| | | | +--- io.netty:netty-codec:4.1.49.Final (*)
| | | | +--- io.netty:netty-codec-socks:4.1.49.Final
| | | | | +--- io.netty:netty-common:4.1.49.Final
| | | | | +--- io.netty:netty-buffer:4.1.49.Final (*)
| | | | | +--- io.netty:netty-transport:4.1.49.Final (*)
| | | | | \--- io.netty:netty-codec:4.1.49.Final (*)
| | | | \--- io.netty:netty-codec-http:4.1.49.Final
| | | | +--- io.netty:netty-common:4.1.49.Final
| | | | +--- io.netty:netty-buffer:4.1.49.Final (*)
| | | | +--- io.netty:netty-transport:4.1.49.Final (*)
| | | | +--- io.netty:netty-codec:4.1.49.Final (*)
| | | | \--- io.netty:netty-handler:4.1.49.Final (*)
| | | +--- io.netty:netty-codec-http:4.1.49.Final (*)
| | | +--- io.netty:netty-codec-http2:4.1.49.Final
| | | | +--- io.netty:netty-common:4.1.49.Final
| | | | +--- io.netty:netty-buffer:4.1.49.Final (*)
| | | | +--- io.netty:netty-transport:4.1.49.Final (*)
| | | | +--- io.netty:netty-codec:4.1.49.Final (*)
| | | | +--- io.netty:netty-handler:4.1.49.Final (*)
| | | | \--- io.netty:netty-codec-http:4.1.49.Final (*)
| | | +--- io.netty:netty-resolver:4.1.49.Final (*)
| | | +--- io.netty:netty-resolver-dns:4.1.49.Final
| | | | +--- io.netty:netty-common:4.1.49.Final
| | | | +--- io.netty:netty-buffer:4.1.49.Final (*)
| | | | +--- io.netty:netty-resolver:4.1.49.Final (*)
| | | | +--- io.netty:netty-transport:4.1.49.Final (*)
| | | | +--- io.netty:netty-codec:4.1.49.Final (*)
| | | | \--- io.netty:netty-codec-dns:4.1.49.Final
| | | | +--- io.netty:netty-common:4.1.49.Final
| | | | +--- io.netty:netty-buffer:4.1.49.Final (*)
| | | | +--- io.netty:netty-transport:4.1.49.Final (*)
| | | | \--- io.netty:netty-codec:4.1.49.Final (*)
| | | +--- com.fasterxml.jackson.core:jackson-core:2.11.3
| | | \--- com.fasterxml.jackson.core:jackson-databind:2.11.3
| | | +--- com.fasterxml.jackson.core:jackson-annotations:2.11.3
| | | \--- com.fasterxml.jackson.core:jackson-core:2.11.3
| | +--- io.vertx:vertx-auth-common:3.9.5
| | | \--- io.vertx:vertx-core:3.9.5 (*)
| | +--- io.vertx:vertx-bridge-common:3.9.5
| | \--- io.vertx:vertx-core:3.9.5 (*)
| +--- io.quarkus.security:quarkus-security:1.1.3.Final
| | +--- org.jboss.logging:jboss-logging:3.3.2.Final -> 3.4.1.Final
| | \--- io.smallrye.reactive:mutiny:0.4.3 -> 0.12.5
| | +--- org.reactivestreams:reactive-streams:1.0.3
| | \--- io.smallrye.common:smallrye-common-annotation:1.5.0
| +--- io.quarkus:quarkus-vertx-core:1.11.0.Final
| | +--- io.quarkus:quarkus-core:1.11.0.Final (*)
| | +--- io.quarkus:quarkus-arc:1.11.0.Final (*)
| | +--- io.quarkus:quarkus-netty:1.11.0.Final
| | | +--- io.netty:netty-codec:4.1.49.Final (*)
| | | +--- io.quarkus:quarkus-core:1.11.0.Final (*)
| | | +--- io.netty:netty-handler:4.1.49.Final (*)
| | | \--- jakarta.enterprise:jakarta.enterprise.cdi-api:2.0.2 (*)
| | \--- io.vertx:vertx-core:3.9.5 (*)
| \--- io.vertx:vertx-web:3.9.5 (*)
\--- io.quarkus:quarkus-resteasy-server-common:1.11.0.Final
+--- io.quarkus:quarkus-core:1.11.0.Final (*)
+--- io.quarkus:quarkus-arc:1.11.0.Final (*)
+--- io.quarkus:quarkus-resteasy-common:1.11.0.Final
| +--- io.quarkus:quarkus-core:1.11.0.Final (*)
| +--- org.jboss.resteasy:resteasy-core:4.5.8.SP1
| | +--- org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.1_spec:2.0.1.Final
| | +--- org.jboss.spec.javax.xml.bind:jboss-jaxb-api_2.3_spec:1.0.1.Final -> 2.0.0.Final
| | +--- org.jboss.resteasy:resteasy-core-spi:4.5.8.SP1
| | | +--- org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.1_spec:2.0.1.Final
| | | +--- org.jboss.spec.javax.xml.bind:jboss-jaxb-api_2.3_spec:1.0.1.Final -> 2.0.0.Final
| | | +--- org.reactivestreams:reactive-streams:1.0.3
| | | +--- jakarta.validation:jakarta.validation-api:2.0.2
| | | +--- com.sun.activation:jakarta.activation:1.2.1
| | | \--- org.jboss.logging:jboss-logging:3.3.2.Final -> 3.4.1.Final
| | +--- org.reactivestreams:reactive-streams:1.0.3
| | +--- jakarta.validation:jakarta.validation-api:2.0.2
| | +--- com.ibm.async:asyncutil:0.1.0
| | +--- com.sun.activation:jakarta.activation:1.2.1
| | +--- org.jboss.logging:jboss-logging:3.3.2.Final -> 3.4.1.Final
| | +--- org.eclipse.microprofile.config:microprofile-config-api:1.4
| | \--- io.smallrye.config:smallrye-config:1.6.1 -> 1.10.0 (*)
| +--- io.quarkus:quarkus-arc:1.11.0.Final (*)
| \--- com.sun.activation:jakarta.activation:1.2.1
\--- jakarta.validation:jakarta.validation-api:2.0.2
(c) - dependency constraint
(*) - dependencies omitted (listed previously)
5. Quarkus JAX-RX endpoint
5.1 A default HelloResource.java
is generated to provide a /hello
endpoint.
package com.mkyong.quarkus;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/hello")
public class HelloResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello RESTEasy";
}
}
5.2 Also a RestAssured unit test for the above endpoint.
package com.mkyong.quarkus;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
@QuarkusTest
public class HelloResourceTest {
@Test
public void testHelloEndpoint() {
given()
.when().get("/hello")
.then()
.statusCode(200)
.body(is("Hello RESTEasy"));
}
}
6. Quarkus and Dockerfile
The quarkus-maven-plugin
also generates three Dockerfile
files to build a Docker container for the JAR file or the native executable.
Dockerfile.fast-jar
– Build a docker container for the JAR file, this is a new packaging format (Fast-jar) since Quarkus 1.5 released, for faster startup times.Dockerfile.jvm
– Build a docker container for the JAR file.Dockerfile.native
– Build a docker container for native executable.
6.1 Review the Dockerfile.jvm
.
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# ./gradlew build
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-hello-world-gradle-jvm .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/quarkus-hello-world-gradle-jvm
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-hello-world-gradle-jvm
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
COPY build/lib/* /deployments/lib/
COPY build/*-runner.jar /deployments/app.jar
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]
6.2 Review the Dockerfile.native
.
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
#
# Before building the container image run:
#
# ./gradlew build -Dquarkus.package.type=native
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-hello-world-gradle .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/quarkus-hello-world-gradle
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root build/*-runner /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
7. Gradle run Quarkus in Dev Mode
7.1 In a separated terminal, type command gradlew quarkusDev
will run Quarkus application in development mode and by default, enabling hot deployment with background compilation, which means if we modify some code, the changes will automatically take effect.
By default, the Quarkus application starts at port 8080
.
> gradlew quarkusDev
OpenJDK 64-Bit Server VM warning: forcing TieredStopAtLevel to full optimization because JVMCI is enabled
Listening for transport dt_socket at address: 5005
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2021-01-27 15:30:16,034 INFO [io.quarkus] (Quarkus Main Thread) quarkus-hello-world-gradle 1.0.0-SNAPSHOT on JVM
(powered by Quarkus 1.11.0.Final) started in 2.051s. Listening on: http://localhost:8080
2021-01-27 15:30:16,052 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2021-01-27 15:30:16,053 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy]
<==========---> 80% EXECUTING [3m 16s]
> :quarkusDev
7.2 Access the /hello
endpoint.
> curl http://localhost:8080/hello
Hello RESTEasy
7.3 We modify the /hello
endpoint to return a list, and save it.
package com.mkyong.quarkus;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Arrays;
import java.util.List;
@Path("/hello")
public class HelloResource {
List<String> list = Arrays.asList("A", "B", "C");
@GET
@Produces(MediaType.TEXT_PLAIN)
public List<String> hello() {
//return "Hello RESTEasy";
return list;
}
}
7.4 Back to the terminal that starts the Quarkus application, the vert.x-worker-thread
will detect the changed file and do hot replace automatically.
2021-01-27 15:46:18,544 INFO [io.qua.dep.dev.RuntimeUpdatesProcessor] (vert.x-worker-thread-17) Hot replace total time: 0.484s
7.5 Test the /hello
endpoint again.
> curl http://localhost:8080/hello
[A, B, C]
7.6 CTRL + C to stop the running Quarkus application.
Further Reading
Download Source Code
$ git clone https://github.com/mkyong/quarkus
$ cd quarkus-hello-world-gradle
$ gradlew quarkusDev
$ curl http://localhost:8080/hello