////
This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Building Quarkus apps with Gradle

include::./attributes.adoc[]

== Gradle configuration

Configure your project as indicated in the link:gradle-config.html[Gradle configuration page].

At the moment there is no way of automatically generating a new project using the Quarkus Gradle plugin,
luckily setting up a Quarkus project with Gradle is very simple. You only need to add the Quarkus Gradle plugin like this:

[source,groovy,subs=attributes+]
----
plugins {
    id 'java'
}

apply plugin: 'io.quarkus'
----

or, if you use the Gradle Kotlin DSL:

[source,kotlin,subs=attributes+]
----
plugins {
    java
}

apply(plugin = "io.quarkus")
----

=== Gradle configuration for a local SNAPSHOT version of Quarkus

This paragraph is relevant for those who want to use a locally built version of Quarkus, instead of an official release. It appears the configuration described above will not work in this case due to an issue in Gradle. There is a workaround though that looks a bit more verbose but nevertheless works for both locally built and officially released versions.

[source,groovy,subs=attributes+]
----
buildscript {
    repositories {
        mavenLocal()
    }
    dependencies {
        classpath "io.quarkus:quarkus-gradle-plugin:999-SNAPSHOT"
    }
}

plugins {
    id 'java'
}

apply plugin: 'io.quarkus'
----

or, if you use the Gradle Kotlin DSL:

[source,kotlin,subs=attributes+]
----

buildscript {
    repositories {
        mavenLocal()
    }
    dependencies {
        classpath("io.quarkus:quarkus-gradle-plugin:999-SNAPSHOT")
    }
}

plugins {
    java
}

apply(plugin = "io.quarkus")
----


[[project-creation]]
== Creating a new project

For now we have to manually create a Gradle project file for Quarkus.
Here is a complete sample file for a simple REST project:

[source,groovy,subs=attributes+]
----
plugins {
    id 'java'
    id 'io.quarkus' version '{quarkus-version}' // <1>
}

repositories {
    mavenCentral()
}

dependencies { // <2>
    implementation enforcedPlatform('io.quarkus:quarkus-bom:{quarkus-version}')
    implementation 'io.quarkus:quarkus-resteasy'
}
----

<1> The Quarkus plugin needs to be applied.
<2> We include the Quarkus BOM using Gradle's link:https://docs.gradle.org/5.4.1/userguide/managing_transitive_dependencies.html#sec:bom_import[relevant syntax] and add RESTEasy dependency since we are developing a REST application similar to the getting started example.
Quarkus also need this dependency for running tests, to provide this we use the `implementation` configuration.

Here's the same build script, using the Gradle Kotlin DSL:

[source,kotlin,subs=attributes+]
----
plugins {
    java
}
apply(plugin = "io.quarkus")

repositories {
    mavenCentral()
}

dependencies {
    implementation(enforcedPlatform("io.quarkus:quarkus-bom:{quarkus-version}"))
    implementation("io.quarkus:quarkus-resteasy")
}
----

== Enable Tests

Quarkus uses Junit5 and to enable it in Gradle we need to add a section to our build file:

[source,groovy,subs=attributes+]
----
test {
  useJUnitPlatform()
}
----

Using the Kotlin DSL, add:

[source,kotlin,subs=attributes+]
----
tasks.test {
    useJUnitPlatform()
}
----

To follow up our Rest example from above, we would also need to add two test dependencies:

[source,groovy,subs=attributes+]
----
testCompile group: 'io.quarkus', name: 'quarkus-junit5', version: '{quarkus-version}'
testCompile group: 'io.rest-assured', name: 'rest-assured', version: '{restassured-version}'
----

For the Kotlin DSL:

[source,kotlin,subs=attributes+]
----
testCompile("io.quarkus:quarkus-junit5:{quarkus-version}")
testCompile("io.rest-assured:rest-assured:{restassured-version}")
----

Note: Quarkus do not allow both link:getting-started-testing.html[QuarkusTests] and link:getting-started-testing.html#native-executable-testing[SubstrateTests] to run in the same test run.
SubstrateTests should be seen as integration tests and moved to a different folder
as recommended here:
https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests[Configuring integration tests].
Quarkus supports running Substrate tests with Gradle, but the `buildNative` task is required to be completed first.

[[custom-test-configuration-profile]]
=== Custom test configuration profile in JVM mode

By default, Quarkus tests in JVM mode are run using the `test` configuration profile. If you are not familiar with Quarkus
configuration profiles, everything you need to know is explained in the
link:application-configuration-guide.html#configuration-profiles[Configuration Profiles Documentation].

It is however possible to use a custom configuration profile for your tests with the Gradle build configuration shown below.
This can be useful if you need for example to run some tests using a specific database which is not your default testing
database.

[source,groovy,subs=attributes+]
----
test {
    useJUnitPlatform()
    systemProperty "quarkus.test.profile", "foo" <1>
}
----

or, if you use the Gradle Kotlin DSL:

[source,kotlin,subs=attributes+]
----
tasks.test {
    useJUnitPlatform()
    systemProperty("quarkus.test.profile", "foo") <1>
 }
----

<1> The `foo` configuration profile will be used to run the tests.

[WARNING]
====
It is not possible to use a custom test configuration profile in native mode for now. Native tests are always run using the
`prod` profile.
====

== Dealing with extensions

From inside a Quarkus project, you can obtain a list of the available extensions with:

[source,shell]
----
./gradlew listExtensions
----

You can enable an extension using:

[source,shell]
----
./gradlew addExtension --extensions="hibernate-validator"
----

Extensions are passed using a comma-separated list.

The extension name is the GAV name of the extension: e.g. `io.quarkus:quarkus-agroal`.
But you can pass a partial name and Quarkus will do its best to find the right extension.
For example, `agroal`, `Agroal` or `agro`  will expand to `io.quarkus:quarkus-agroal`.
If no extension is found or if more than one extensions match, you will see a red check mark  ❌ in the command result.

[source,shell]
----
./gradlew addExtension --extensions="jdbc,agroal,non-exist-ent"
[...]
❌ Multiple extensions matching 'jdbc'
     * io.quarkus:quarkus-jdbc-h2
     * io.quarkus:quarkus-jdbc-mariadb
     * io.quarkus:quarkus-jdbc-postgresql
     Be more specific e.g using the exact name or the full gav.
✅ Adding extension io.quarkus:quarkus-agroal
❌ Cannot find a dependency matching 'non-exist-ent', maybe a typo?
[...]
----

You can install all extensions wich match a globbing pattern :

[source,shell]
----
./gradlew addExtension --extensions="hibernate*"
----

== Development mode

Quarkus comes with a built-in development mode.
Run your application with:

[source,shell]
----
./gradlew quarkusDev
----

You can then update the application sources, resources and configurations.
The changes are automatically reflected in your running application.
This is great to do development spanning UI and database as you see changes reflected immediately.

`quarkusDev` enables hot deployment with background compilation, which means that when you modify
your Java files 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.
The act of refreshing the browser triggers a scan of the workspace, and if any changes are detected the
Java files are compiled, and the application is redeployed, then your request is serviced by the
redeployed application. If there are any issues with compilation or deployment an error page will let you know.

Hit `CTRL+C` to stop the application.

You can change the working directory the development environment runs on:

----
quarkusDev {
    workingDir = rootProject.projectDir
}
----

== Debugging

In development mode, Quarkus starts by default with debug mode enabled, listening to port `5005` without suspending the JVM.

This behavior can be changed by giving the `debug` system property one of the following values:

* `false` - the JVM will start with debug mode disabled
* `true` - the JVM will start in debug mode and be suspended until a debugger is attached to port `5005`
* `client` - the JVM will start in client mode and attempt to connect to `localhost:5005`
* `{port}` - the JVM will start in debug mode and be suspended until a debugger is attached to `{port}`

[TIP]
====
You can also run a Quarkus application in debug mode with a suspended JVM using `./gradlew quarkusDev -Ddebug` which is a shorthand for `./gradlew quarkusDev -Ddebug=true`.

Then, attach your debugger to `localhost:5005`.
====

== Import in your IDE

Once you have a <<project-creation, project generated>>, you can import it in your favorite IDE.
The only requirement is the ability to import a Gradle project.

**Eclipse**

In Eclipse, click on: `File -> Import`.
In the wizard, select: `Gradle -> Existing Gradle Project`.
On the next screen, select the root location of the project.
The next screen list the found modules; select the generated project and click on `Finish`. Done!

In a separated terminal, run `./gradlew quarkusDev`, and enjoy a highly productive environment.

**IntelliJ**

In IntelliJ:

1. From inside IntelliJ select `File -> New -> Project From Existing Sources...` or, if you are on the welcome dialog, select `Import project`.
2. Select the project root
3. Select `Import project from external model` and `Gradle`
4. Next a few times (review the different options if needed)
5. On the last screen click on Finish

In a separated terminal or in the embedded terminal, run `./gradlew quarkusDev`. Enjoy!

**Apache Netbeans**

In Netbeans:

1. Select `File -> Open Project`
2. Select the project root
3. Click on `Open Project`

In a separated terminal or the embedded terminal, go to the project root and run `./gradlew quarkusDev`. Enjoy!

**Visual Studio Code**

Open the project directory in VS Code. If you have installed the Java Extension Pack (grouping a set of Java extensions), the project is loaded as a Gradle project.

== Building a native executable

Native executables make Quarkus applications ideal for containers and serverless workloads.

Make sure to have `GRAALVM_HOME` configured and pointing to GraalVM version {graalvm-version}.

Create a native executable using: `./gradlew buildNative`.
A native executable will be present in `build/`.

=== Build a container friendly executable

The native executable will be specific to your operating system.
To create an executable that will run in a container, use the following:

[source,shell]
----
./gradlew buildNative
----

==== Customize the build native task

There are situations where it may be required to alter the default values of the `buildNative` task (whose implementation can be found link:https://github.com/quarkusio/quarkus/blob/master/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusNative.java[here]).

The easiest way to supply custom configuration is via the command line. For example to use docker to build the native image, simply add the `--docker-build=true` flag like so:

[source,shell]
----
./gradlew buildNative --docker-build=true
----

The produced executable will be a 64 bit Linux executable, so depending on your operating system
it may no longer be runnable.
However, it's not an issue as we are going to copy it to a Docker container.

Another way of customizing the native build image build process is to configure the task inside the Gradle build script. If for example it is required to set the `enableHttpUrlHandler`, it can be done like so:

[source,groovy]
----
buildNative {
    enableHttpUrlHandler = true
}
----

or, if you use the Gradle Kotlin DSL:

[source,kotlin,subs=attributes+]
----
tasks {
    named<QuarkusNative>("buildNative") {
        setEnableHttpUrlHandler(true)
    }
}
----


The native executable would then be produced by executing:

[source,shell]
----
./gradlew buildNative
----

== Building Uber-Jars

Quarkus Gradle plugin supports the generation of Uber-Jars by specifying an `--uber-jar` argument as follows:

[source,shell]
----
./gradlew quarkusBuild --uber-jar
----

When building an Uber-Jar you can specify entries that you want to exclude from the generated jar by using the `--ignored-entry` argument:

[source,shell]
----
./gradlew quarkusBuild --uber-jar --ignored-entry=META-INF/file1.txt
----

The entries are relative to the root of the generated Uber-Jar. You can specify multiple entries by adding extra `--ignored-entry` arguments.


