# Creating Your First Application

Learn how to create a Hello World Quarkus app. This guide covers:

- Bootstrapping an application

- Creating a Jakarta REST endpoint

- Injecting beans

- Functional tests

- Packaging of the application

## 1. Prerequisites

To complete this guide, you need:

- Roughly 15 minutes

- An IDE

- JDK 17+ installed with `JAVA_HOME` configured appropriately

- Apache Maven 3.9.9

- Optionally the Quarkus CLI if you want to use it

| Verify Maven is using the Java you expect 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 `mvn --version`.

## 2. Architecture

In this guide, we create a straightforward application serving a `hello` endpoint. To demonstrate dependency injection, this endpoint uses a `greeting` bean.

This guide also covers the testing of the endpoint.

## 3. Solution

We recommend that you follow the instructions from Bootstrapping the project and onwards to create the application step by step.

However, you can go right to the completed example.

Download an archive or clone the git repository:

    git clone https://github.com/quarkusio/quarkus-quickstarts.git

The solution is located in the `getting-started` directory.

## 4. Bootstrapping the project

The easiest way to create a new Quarkus project is to open a terminal and run the following command:

CLI

    quarkus create app org.acme:getting-started \
        --extension='rest'
    cd getting-started

To create a Gradle project, add the `--gradle` or `--gradle-kotlin-dsl` option.

For more information about how to install and use the Quarkus CLI, see the Quarkus CLI guide.

Maven

    mvn io.quarkus.platform:quarkus-maven-plugin:3.26.0.CR1:create \
        -DprojectGroupId=org.acme \
        -DprojectArtifactId=getting-started \
        -Dextensions='rest'
    cd getting-started

To create a Gradle project, add the `-DbuildTool=gradle` or `-DbuildTool=gradle-kotlin-dsl` option.

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"`

It generates the following in `./getting-started`:

- the Maven structure

- an `org.acme.GreetingResource` resource exposed on `/hello`

- an associated unit test

- a landing page that is accessible on `http://localhost:8080` after starting the application

- example `Dockerfile` files for both `native` and `jvm` modes in `src/main/docker`

- the application configuration file

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

If we focus on the dependencies section, you can see the extension allowing the development of REST applications:

pom.xml

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-rest</artifactId>
    </dependency>

build.gradle

    implementation("io.quarkus:quarkus-rest")

### 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 Quarkus REST";
        }
    }

It’s a very simple REST endpoint, returning "Hello from Quarkus REST" to requests on "/hello".

| Differences with vanilla Jakarta REST With Quarkus, there is no need to create an `Application` class. It’s supported, but not required. In addition, only one instance of the resource is created and not one per request. You can configure this using the different `*Scoped` annotations (`ApplicationScoped`, `RequestScoped`, etc).

## 5. Running the application

Now we are ready to run our application:

CLI

    quarkus dev

Maven

    ./mvnw quarkus:dev

Gradle

    ./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, rest]

Once started, you can request the provided endpoint:

    $ curl -w "\n" http://localhost:8080/hello
    Hello from Quarkus REST

Hit `CTRL+C` to stop the application, or keep it running and enjoy the blazing fast hot-reload.

| Automatically add newline with `curl -w "\n"` We are using `curl -w "\n"` in this example to avoid your terminal printing a '%' or put both result and next command prompt on the same line.

## 6. Using injection

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-rest` 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;
        }

    }

Edit the `GreetingResource` class to inject the `GreetingService` and create a new endpoint using it:

    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 Quarkus REST";
        }
    }

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:

CLI

    quarkus dev

Maven

    ./mvnw quarkus:dev

Gradle

    ./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:

pom.xml

    <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>

build.gradle

    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 Quarkus REST"));
        }

        @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:

CLI

    quarkus build

Maven

    ./mvnw install

Gradle

    ./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 the `quarkus-run.jar` jar file - being an executable jar. Be aware that it’s not an über-jar as the dependencies are copied into subdirectories of `quarkus-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.

All CDI beans implementing the `InfoContributor` will be picked up and their data will be appended to the endpoint.

#### 12.1.1. Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property | Type | Default
--- | --- | ---
`quarkus.info.enabled` Whether the info endpoint will be enabled Environment variable: `QUARKUS_INFO_ENABLED` | boolean | `true`
`quarkus.info.path` The path under which the info endpoint will be located Environment variable: `QUARKUS_INFO_PATH` | string | `info`
`quarkus.info.git.enabled` Whether git info will be included in the info endpoint Environment variable: `QUARKUS_INFO_GIT_ENABLED` | boolean | `true`
`quarkus.info.git.mode` Controls how much information is present in the git section Environment variable: `QUARKUS_INFO_GIT_MODE` | `standard`, `full` | `standard`
`quarkus.info.build.enabled` Whether build info will be included in the info endpoint Environment variable: `QUARKUS_INFO_BUILD_ENABLED` | boolean | `true`
`quarkus.info.build."property-key"` Additional properties to be added to the build section Environment variable: `QUARKUS_INFO_BUILD__PROPERTY_KEY_` | Map<String,String> |
`quarkus.info.os.enabled` Whether os info will be included in the info endpoint Environment variable: `QUARKUS_INFO_OS_ENABLED` | boolean | `true`
`quarkus.info.java.enabled` Whether java info will be included in the info endpoint Environment variable: `QUARKUS_INFO_JAVA_ENABLED` | boolean | `true`

## 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