Creating Your First Application
了解如何创建Quarkus Hello World 应用程序。 本指南涵盖:
-
搭建应用程序
-
Creating a Jakarta REST endpoint
-
注入beans
-
功能测试
-
应用打包
1. 准备
要完成本指南,您需要:
-
Roughly 15 minutes
-
An IDE
-
JDK 11+ installed with
JAVA_HOME
configured appropriately -
Apache Maven 3.9.6
-
Optionally the Quarkus CLI if you want to use it
验证 Maven 是否使用了预期的Java
If you have multiple JDK’s installed, it is not certain Maven will pick up
the expected java and you could end up with unexpected results. You can
verify which JDK Maven uses by running |
3. 完整源码
We recommend that you follow the instructions from Bootstrapping the project and onwards to create the application step by step.
当然您也可以直接查看完成后的代码。
下载 压缩包 或克隆 git 仓库:
git clone https://github.com/quarkusio/quarkus-quickstarts.git
The solution is located in the getting-started
directory.
4. 搭建项目
创建 Quarkus 项目最简单方法是打开命令行并运行以下命令:
For Windows users:
-
If using cmd, (don’t use backward slash
\
and put everything on the same line) -
If using Powershell, wrap
-D
parameters in double quotes e.g."-DprojectArtifactId=getting-started"
上边命令会在 ./getting-started
中生成:
-
Maven 目录结构
-
an
org.acme.GreetingResource
resource exposed on/hello
-
相关单元测试
-
启动应用程序后可访问
http://localhost:8080
入口页 -
src/main/docker
有Dockerfile
样例文件, 包含native
及jvm
模式 -
应用程序配置文件
Once generated, look at the pom.xml
. You will find the import of the
Quarkus BOM, allowing you to omit the version of the different Quarkus
dependencies. In addition, you can see the quarkus-maven-plugin
responsible of the packaging of the application and also providing the
development mode.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
In a Gradle project, you would find a similar setup:
-
the Quarkus Gradle plugin
-
an
enforcedPlatform
directive for the Quarkus BOM
如果我们关注 dependencies 部分,您可以看到用于支持 REST 程序开发的扩展:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
implementation("io.quarkus:quarkus-resteasy-reactive")
4.1. The Jakarta REST resources
During the project creation, the
src/main/java/org/acme/GreetingResource.java
file has been created with
the following content:
package org.acme;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from RESTEasy Reactive";
}
}
It’s a very simple REST endpoint, returning "Hello from RESTEasy Reactive" to requests on "/hello".
Differences with vanilla Jakarta REST
使用 Quarkus,不需要创建 |
5. 运行应用
Now we are ready to run our application:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
[INFO] --------------------< org.acme:getting-started >---------------------
[INFO] Building getting-started 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ getting-started ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory <path>/getting-started/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ getting-started ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to <path>/getting-started/target/classes
[INFO]
[INFO] --- quarkus-maven-plugin:<version>:dev (default-cli) @ getting-started ---
Listening for transport dt_socket at address: 5005
2019-02-28 17:05:22,347 INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation
2019-02-28 17:05:22,635 INFO [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 288ms
2019-02-28 17:05:22,770 INFO [io.quarkus] (main) Quarkus started in 0.668s. Listening on: http://localhost:8080
2019-02-28 17:05:22,771 INFO [io.quarkus] (main) Installed features: [cdi, resteasy-reactive]
启动后,可以请求提供的接口:
$ curl -w "\n" http://localhost:8080/hello
Hello from RESTEasy Reactive
按 CTRL+C 停止应用程序,或者让它继续运行并享受超快的热加载。
用
curl -w "\n" 自动添加换行在本例中,我们使用 |
6. 使用注入
Dependency injection in Quarkus is based on ArC which is a CDI-based dependency injection solution tailored for Quarkus' architecture. If you’re new to CDI then we recommend you to read the Introduction to CDI guide.
Quarkus only implements a subset of the CDI features and comes with non-standard features and specific APIS, you can learn more about it in the Contexts and Dependency Injection guide.
ArC comes as a dependency of quarkus-resteasy-reactive
so you already have
it handy.
Let’s modify the application and add a companion bean. Create the
src/main/java/org/acme/GreetingService.java
file with the following
content:
package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GreetingService {
public String greeting(String name) {
return "hello " + name;
}
}
编辑 GreetingResource
类注入 GreetingService
并在一个新接口中使用它:
package org.acme;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@Inject
GreetingService service;
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/greeting/{name}")
public String greeting(String name) {
return service.greeting(name);
}
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from RESTEasy Reactive";
}
}
If you stopped the application (keep in mind you don’t have to do it, changes will be automatically deployed by our live reload feature), restart the application with:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
Then check that the endpoint returns hello quarkus
as expected:
$ curl -w "\n" http://localhost:8080/hello/greeting/quarkus
hello quarkus
7. Development Mode
quarkus:dev
runs Quarkus in development mode. This enables live reload
with background compilation, which means that when you modify your Java
files and/or your resource files and refresh your browser, these changes
will automatically take effect. This works too for resource files like the
configuration property file. Refreshing the browser triggers a scan of the
workspace, and if any changes are detected, the Java files are recompiled
and the application is redeployed; your request is then serviced by the
redeployed application. If there are any issues with compilation or
deployment an error page will let you know.
This will also listen for a debugger on port 5005
. If you want to wait for
the debugger to attach before running you can pass -Dsuspend
on the
command line. If you don’t want the debugger at all you can use
-Ddebug=false
.
8. Testing
All right, so far so good, but wouldn’t it be better with a few tests, just in case.
In the generated build file, you can see 2 test dependencies:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
testImplementation("io.quarkus:quarkus-junit5")
testImplementation("io.rest-assured:rest-assured")
Quarkus supports JUnit 5 tests.
Because of this, in the case of Maven, the version of the Surefire Maven Plugin must be set, as the default version does not support JUnit 5:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
We also set the java.util.logging
system property to make sure tests will
use the correct log manager and maven.home
to ensure that custom
configuration from ${maven.home}/conf/settings.xml
is applied (if any).
The generated project contains a simple test. Edit the
src/test/java/org/acme/GreetingResourceTest.java
to match the following
content:
package org.acme;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import java.util.UUID;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
@QuarkusTest
public class GreetingResourceTest {
@Test (1)
public void testHelloEndpoint() {
given()
.when().get("/hello")
.then()
.statusCode(200) (2)
.body(is("Hello from RESTEasy Reactive"));
}
@Test
public void testGreetingEndpoint() {
String uuid = UUID.randomUUID().toString();
given()
.pathParam("name", uuid)
.when().get("/hello/greeting/{name}")
.then()
.statusCode(200)
.body(is("hello " + uuid));
}
}
1 | By using the QuarkusTest runner, you instruct JUnit to start the
application before the tests. |
2 | Check the HTTP response status code and content |
These tests use RestAssured, but feel free to use your favorite library.
You can run these using Maven:
./mvnw test
You can also run the test from your IDE directly (be sure you stopped the application first).
By default, tests will run on port 8081
so as not to conflict with the
running application. We automatically configure RestAssured to use this
port. If you want to use a different client you should use the
@TestHTTPResource
annotation to directly inject the URL of the tested
application into a field on the test class. This field can be of the type
String
, URL
or URI
. This annotation can also be given a value for the
test path. For example, if I want to test a Servlet mapped to /myservlet
I
would just add the following to my test:
@TestHTTPResource("/myservlet")
URL testUrl;
The test port can be controlled via the quarkus.http.test-port
config
property. Quarkus also creates a system property called test.url
that is
set to the base test URL for situations where you cannot use injection.
9. Working with multi-module project or external modules
Quarkus heavily utilizes Jandex at build time, to discover various classes or annotations. One immediately recognizable application of this, is CDI bean discovery. As a result, most of the Quarkus extensions will not work properly if this build time discovery isn’t properly setup.
This index is created by default on the project on which Quarkus is configured for, thanks to our Maven and Gradle plugins.
However, when working with a multi-module project, be sure to read the
Working with multi-module projects
section of the
Maven or
Gradle guides.
If you plan to use external modules (for example, an external library for
all your domain objects), you will need to make these modules known to the
indexing process either by adding the Jandex plugin (if you can modify them)
or via the quarkus.index-dependency
property inside your
application.properties
(useful in cases where you can’t modify the
module).
Be sure to read the Bean Discovery section of the CDI guide for more information.
10. Packaging and run the application
The application is packaged using:
quarkus build
./mvnw install
./gradlew build
It produces several outputs in /target
:
-
getting-started-1.0.0-SNAPSHOT.jar
- containing just the classes and resources of the projects, it’s the regular artifact produced by the Maven build - it is not the runnable jar; -
the
quarkus-app
directory which contains thequarkus-run.jar
jar file - being an executable jar. Be aware that it’s not an über-jar as the dependencies are copied into subdirectories ofquarkus-app/lib/
.
You can run the application using: java -jar
target/quarkus-app/quarkus-run.jar
If you want to deploy your application somewhere (typically in a container),
you need to deploy the whole quarkus-app directory.
|
Before running the application, don’t forget to stop the hot reload mode
(hit CTRL+C ), or you will have a port conflict.
|
11. Configuring the banner
By default, when a Quarkus application starts (in regular or dev mode), it
will display an ASCII art banner. The banner can be disabled by setting
quarkus.banner.enabled=false
in application.properties
, by setting the
-Dquarkus.banner.enabled=false
Java System Property, or by setting the
QUARKUS_BANNER_ENABLED
environment variable to false
. Furthermore,
users can supply a custom banner by placing the banner file in
src/main/resources
and configuring quarkus.banner.path=name-of-file
in
application.properties
.
12. Non Application endpoints
Various Quarkus extensions contribute non-application endpoints that provide different kinds of information about the application. Examples of such extensions are the health, metrics, OpenAPI and info extensions.
These non application endpoints are normally accessible under the /q
prefix like so:
-
/q/health
-
/q/metrics
-
/q/openapi
-
/q/info
but users can also choose to expose one that might present a security risk under a different TCP port using a dedicated management interface.
12.1. Info endpoint
If the application contains the quarkus-info
extension, then Quarkus will
by default expose the /q/info
endpoint which provides information about
the build, java version, version control, and operating system. The level of
detail of the exposed information is configurable.
12.1.1. Configuration Reference
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Type |
Default |
|
---|---|---|
Whether the info endpoint will be enabled Environment variable: Show more |
boolean |
|
The path under which the info endpoint will be located Environment variable: Show more |
string |
|
Whether git info will be included in the info endpoint Environment variable: Show more |
boolean |
|
Controls how much information is present in the git section Environment variable: Show more |
|
|
Whether build info will be included in the info endpoint Environment variable: Show more |
boolean |
|
Whether os info will be included in the info endpoint Environment variable: Show more |
boolean |
|
Whether java info will be included in the info endpoint Environment variable: Show more |
boolean |
|
Additional properties to be added to the build section Environment variable: Show more |
|
13. What’s next?
This guide covered the creation of an application using Quarkus. However, there is much more. We recommend continuing the journey by creating your second Quarkus application, with dev services and persistence. You can learn about creating a native executable and packaging it in a container with the building a native executable guide. If you are interested in reactive, we recommend the getting started with reactive guide, where you can see how to implement reactive applications with Quarkus.
In addition, the tooling guide document explains how to:
-
scaffold a project in a single command line
-
enable the development mode (hot reload)
-
import the project in your favorite IDE
-
and more