As an application developer, you can use IBM Enterprise Build of Quarkus to create microservices-based applications written in Java that run on OpenShift and serverless environments. Applications compiled to native executables have small memory footprints and fast startup times.
You can configure your Quarkus application by setting properties in the application.properties file.
You can also extend and customize the configuration for your application by doing the following:
-
Substituting and composing configuration property values by using property expressions
-
Implementing MicroProfile-compliant classes with custom configuration sources that read configuration values from different external sources
-
Using configuration profiles to keep separate sets of configuration values for your development, test, and production environments
The procedures include configuration examples that are created by using the Quarkus config-quickstart exercise.
|
Note:
Alternatively, you can configure your Quarkus application by updating the |
Prerequisites
-
You have installed OpenJDK 17 or 21 and set the
JAVA_HOMEenvironment variable to specify the location of the Java SDK.-
To download the Red Hat build of OpenJDK, log in to the Red Hat Customer Portal and go to Software Downloads.
-
-
You have installed Apache Maven 3.9.9.
-
Download Maven from the Apache Maven Project website.
-
-
You have configured Maven to use artifacts from the Quarkus Maven repository.
-
To learn how to configure Maven settings, see Getting started with Quarkus.
-
Configuration options
You can manage your application’s settings in a single configuration file. Additionally, you can define configuration profiles to group related settings for different environments, such as development, testing, or production. This way, you can easily switch between profiles and apply environment-specific properties without altering your main configuration file.
By default, Quarkus reads properties from the application.properties file located in the src/main/resources directory.
If, instead, you prefer to configure and manage application properties in an application.yaml file, add the quarkus-config-yaml dependency to your project’s pom.xml file.
For more information, see Adding YAML configuration support.
IBM Enterprise Build of Quarkus also supports MicroProfile Config, which you can use to load your application’s configuration from various sources. By using the MicroProfile Config specification from the Eclipse MicroProfile project, you can inject configuration properties into your application and access them by using methods defined in your code.
Quarkus can read application properties from different origins, including:
-
The file system
-
A database
-
A Kubernetes or OpenShift Container Platform
ConfigMaporSecretobject -
Any source that a Java application can load
Creating the configuration quickstart project
With the config-quickstart project, you can get up and running with a simple Quarkus application by using Apache Maven and the Quarkus Maven plugin.
The following procedure describes how you can create a Quarkus Maven project.
-
You have installed OpenJDK 17 or 21 and set the
JAVA_HOMEenvironment variable to specify the location of the Java SDK.-
To download Red Hat build of OpenJDK, log in to the Red Hat Customer Portal and go to Software Downloads.
-
-
You have installed Apache Maven 3.9.9.
-
Download Maven from the Apache Maven Project website.
-
-
Verify that Maven uses OpenJDK 17 or 21 and that the Maven version is 3.9.9:
mvn --version -
If the
mvncommand does not return OpenJDK 17 or 21, ensure that the directory where OpenJDK 17 or 21 is installed on your system is included in thePATHenvironment variable:export PATH=$PATH:<path_to_JDK> -
Enter the following command to generate the project:
mvn com.redhat.quarkus.platform:quarkus-maven-plugin:3.27.1.redhat-00003:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=config-quickstart \ -DplatformGroupId=com.redhat.quarkus.platform \ -DplatformVersion=3.27.1.redhat-00003 \ -DclassName="org.acme.config.GreetingResource" \ -Dpath="/greeting" cd config-quickstart
The preceding mvn command creates the following items in the config-quickstart directory:
-
The Maven project directory structure
-
An
org.acme.config.GreetingResourceresource -
A landing page that you can access at
http://localhost:8080after you start the application -
Associated unit tests for testing your application in native mode and JVM mode
-
Example
Dockerfile.jvmandDockerfile.nativefiles in thesrc/main/dockersubdirectory -
The application configuration file
|
Note:
Alternatively, you can download a Quarkus Maven project to use in this tutorial from the Quarkus Quickstarts archive or clone the Quarkus Quickstarts Git repository.
The Quarkus |
Annotating an interface with @ConfigMapping
Instead of individually injecting multiple related configuration values, use the @io.smallrye.config.ConfigMapping annotation to group configuration properties.
The following procedure describes how you can use the @ConfigMapping annotation on the Quarkus config-quickstart project.
-
You have created the Quarkus
config-quickstartproject. -
You have defined the
greeting.messageandgreeting.nameproperties in theapplication.propertiesfile of your project.
-
Review the
GreetingResource.javafile in your project and ensure that it contains the contents that are shown in the following example. To use the@ConfigPropertyannotation to inject configuration properties from another configuration source into this class, you must import thejava.util.Optionalandorg.eclipse.microprofile.config.inject.ConfigPropertypackages.ExampleGreetingResource.javafilepackage org.acme.config; import java.util.Optional; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import org.eclipse.microprofile.config.inject.ConfigProperty; @Path("/greeting") public class GreetingResource { @ConfigProperty(name = "greeting.message") String message; @ConfigProperty(name = "greeting.suffix", defaultValue="!") String suffix; @ConfigProperty(name = "greeting.name") Optional<String> name; @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return message + " " + name.orElse("world") + suffix; } } -
Create a
GreetingConfiguration.javafile in thesrc/main/java/org/acme/configdirectory. Add the import statements forConfigMappingandOptionalto the file:ExampleGreetingConfiguration.javafilepackage org.acme.config; import io.smallrye.config.ConfigMapping; import io.smallrye.config.WithDefault; import java.util.Optional; @ConfigMapping(prefix = "greeting") (1) public interface GreetingConfiguration { String message(); @WithDefault("!") (2) String suffix(); Optional<String> name(); }1 The prefixproperty is optional. For example, in this scenario, the prefix isgreeting.2 If greeting.suffixis not set,!is used as the default value.
-
Inject the
GreetingConfigurationinstance into theGreetingResourceclass by using the@Injectannotation, as follows:Note: This snippet replaces the three fields that are annotated with
@ConfigPropertythat are in the initial version of theconfig-quickstartproject.ExampleGreetingResource.javafilepackage org.acme.config; 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("/greeting") public class GreetingResource { @Inject GreetingConfiguration config; @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return config.message() + " " + config.name().orElse("world") + config.suffix(); } } -
Compile and start your application in development mode:
./mvnw quarkus:devImportant: If you do not give values for the class properties, the application fails to compile, and an
io.smallrye.config.ConfigValidationExceptionerror is returned to indicate that a value is missing. This does not apply to optional fields or fields with a default value. -
To verify that the endpoint returns the message, enter the following command in a new terminal window:
curl http://localhost:8080/greeting -
You receive the following message:
hello quarkus! -
To stop the application, press Ctrl+C.
Injecting configuration values into your IBM Enterprise Build of Quarkus application
IBM Enterprise Build of Quarkus uses the Configuration for MicroProfile feature to inject configuration data into the application. You can access the configuration by using context and dependency injection (CDI) or by defining a method in your code.
The preferred option for injecting configuration values is to use the @ConfigMapping annotation, however, you can also use the @ConfigProperty annotation.
With the @ConfigProperty annotation, you can map an object property to a key in the MicroProfile Config Sources file of your application.
The following procedure and examples show how you can inject an individual property configuration into a Quarkus config-quickstart project by using the IBM Enterprise Build of Quarkus Application configuration file, application.properties.
|
Note:
You can use the MicroProfile Config properties file ( However, using |
You have created the Quarkus config-quickstart project.
|
Note:
For a completed example of that project, download the
Quarkus Quickstarts archive or clone the Quarkus Quickstarts Git repository and go to the |
-
Open the
src/main/resources/application.propertiesfile. -
Add configuration properties to your configuration file where
<property_name>is the property name and<value>is the value of the property:<property_name>=<value>The following example shows how to set the values for the
greeting.messageand thegreeting.nameproperties in the Quarkusconfig-quickstartproject:Exampleapplication.propertiesfilegreeting.message=hello greeting.name=quarkusImportant: When you are configuring your applications, do not prefix application-specific properties with the string
quarkus. Thequarkusprefix is reserved for configuring Quarkus at the framework level. Usingquarkusas a prefix for application-specific properties might lead to unexpected results when your application runs. -
Review the
GreetingResource.javaJava file in your project. The file contains theGreetingResourceclass with thehello()method that returns a message when you send an HTTP request on the/greetingendpoint:ExampleGreetingResource.javafilepackage org.acme.config; import java.util.Optional; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import org.eclipse.microprofile.config.inject.ConfigProperty; @Path("/greeting") public class GreetingResource { String message; Optional<String> name; String suffix; @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return message + " " + name.orElse("world") + suffix; } }In the example provided, the values of the
messageandnamestrings in thehello()method are not initialized. The application throws aNullPointerExceptionwhen the endpoint is called and starts successfully in this state. -
Define the
message,name, andsuffixfields, and annotate them with@ConfigProperty, matching the values that you defined for thegreeting.messageandgreeting.nameproperties. Use the@ConfigPropertyannotation to inject the configuration value for each string. For example:ExampleGreetingResource.javafilepackage org.acme.config; import java.util.Optional; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import org.eclipse.microprofile.config.inject.ConfigProperty; @Path("/greeting") public class GreetingResource { @ConfigProperty(name = "greeting.message") (1) String message; @ConfigProperty(name = "greeting.suffix", defaultValue="!") (2) String suffix; @ConfigProperty(name = "greeting.name") Optional<String> name; (3) @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return message + " " + name.orElse("world") + suffix; } }1 If you do not configure a value for the greeting.messagestring, the application fails and throws the following exception:jakarta.enterprise.inject.spi.DeploymentException: io.quarkus.runtime.configuration.ConfigurationException: Failed to load config value of type class java.lang.String for: greeting.message2 If you do not configure a value for the greeting.suffix, Quarkus resolves it to the default value.3 If you do not define the greeting.nameproperty, the value ofnameis not available. Your application still runs even when this value is not available because you set theOptionalparameter onname.Note: To inject a configured value, you can use
@ConfigProperty. You do not need to include the@Injectannotation for members that you annotate with@ConfigProperty.
-
Compile and start your application in development mode:
./mvnw quarkus:dev -
Enter the following command in a new terminal window to verify that the endpoint returns the message:
curl http://localhost:8080/greetingThis command returns the following output:
hello quarkus! -
To stop the application, press Ctrl+C.
Updating the functional test to validate configuration changes
Before you test the functionality of your application, you must update the functional test to reflect the changes that you made to the endpoint of your application.
The following procedure shows how you can update your testHelloEndpoint method on the Quarkus config-quickstart project.
-
Open the
GreetingResourceTest.javafile. -
Update the content of the
testHelloEndpointmethod:package org.acme.config; 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 GreetingResourceTest { @Test public void testHelloEndpoint() { given() .when().get("/greeting") .then() .statusCode(200) .body(is("hello quarkus!")); // Modified line } } -
Compile and start your application in development mode:
./mvnw quarkus:dev -
To start running the tests, press
ron your keyboard.
Setting configuration properties
By default, Quarkus reads properties from the application.properties file that is in the src/main/resources directory.
If you change build properties, ensure that you repackage your application.
Quarkus configures most properties during build time. Extensions can define properties as overridable at runtime, for example, the database URL, a user name, and a password, which can be specific to your target environment.
-
You have created the Quarkus
config-quickstartproject. -
You have defined the
greeting.messageandgreeting.nameproperties in theapplication.propertiesfile of your project.
-
To package your Quarkus project, enter the following command:
./mvnw clean package -
Use one of the following methods to set the configuration properties:
-
Setting system properties:
Enter the following command, where
<property_name>is the name of the configuration property that you want to add and<value>is the value of the property:java -D<property_name>=<value> -jar target/quarkus-app/quarkus-run.jarFor example, to set the value of the
greeting.suffixproperty to?, enter the following command:java -Dgreeting.suffix=? -jar target/quarkus-app/quarkus-run.jar -
Setting environment variables:
Enter the following command, where
<property_name>is the name of the configuration property that you want to set and<value>is the value of the property:export <property_name>=<value> ; java -jar target/quarkus-app/quarkus-run.jarNote: Environment variable names follow the conversion rules of MicroProfile Config. MicroProfile Config searches three environment variables for a given property name.
-
Exact match: For example,
foo.BAR.baz. -
Replace each character that is neither alphanumeric nor an underscore (_) with an underscore:
foo_BAR_baz -
Replace each character that is neither alphanumeric nor an underscore (_) with an underscore; then convert the name to upper case:
FOO_BAR_BAZ.
Additionally, the following rules also apply:
-
Properties with double quotes, such as
foo."bar".baz, replace each character that is neither alphanumeric nor an underscore with an underscore:FOOBARBAZ -
Properties with dashes, such as
foo.bar-baz, replace each character that is neither alphanumeric nor an underscore with an underscore:FOO_BAR_BAZ -
An indexed property
foo.bar[0]orfoo.bar[0].baz, replace each character that is neither alphanumeric nor an underscore with an underscore:FOO_BAR_0orFOO_BAR_0__BAZ
-
-
Using an environment file:
Create a
.envfile in your current working directory and add configuration properties, where<PROPERTY_NAME>is the property name and<value>is the value of the property:<PROPERTY_NAME>=<value>Note: In development mode, this file is in the root directory of your project. Do not track the file in version control. If you create a
.envfile in the root directory of your project, you can define keys and values that the program reads as properties. -
Using the
application.propertiesfile:Place the configuration file in the
$PWD/config/application.propertiesdirectory where the application runs so that any runtime properties that are defined in that file override the default configuration.Note: You can also use the
config/application.propertiesfeatures in development mode. Place theconfig/application.propertiesfile inside thetargetdirectory. Any cleaning operation from the build tool, for example,mvn clean, also removes theconfigdirectory.
-
Advanced configuration mapping
The following advanced mapping procedure is an extension that is specific to IBM Enterprise Build of Quarkus and outside of the MicroProfile Config specification.
Using nested object configuration
You can define an interface that is nested inside another interface.
This procedure shows how to create and configure a nested interface in the Quarkus config-quickstart project.
-
You have created the Quarkus
config-quickstartproject. -
You have defined the
greeting.messageandgreeting.nameproperties in theapplication.propertiesfile of your project.
-
Review the
GreetingResource.javain your project. The file contains theGreetingResourceclass with thehello()method that returns a message when you send an HTTP request on the/greetingendpoint:ExampleGreetingResource.javafilepackage org.acme.config; import java.util.Optional; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import org.eclipse.microprofile.config.inject.ConfigProperty; @Path("/greeting") public class GreetingResource { @ConfigProperty(name = "greeting.message") String message; @ConfigProperty(name = "greeting.suffix", defaultValue="!") String suffix; @ConfigProperty(name = "greeting.name") Optional<String> name; @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return message + " " + name.orElse("world") + suffix; } } -
Create a
GreetingConfiguration.javaclass file with theGreetingConfigurationinstance. This class contains the externalized configuration for thehello()method that is defined in theGreetingResourceclass:ExampleGreetingConfiguration.javafilepackage org.acme.config; import io.smallrye.config.ConfigMapping; import io.smallrye.config.WithDefault; import java.util.Optional; @ConfigMapping(prefix = "greeting") public interface GreetingConfiguration { String message(); @WithDefault("!") String suffix(); Optional<String> name(); } -
Create the
ContentConfiginterface that is nested inside theGreetingConfigurationinstance, as shown in the following example:ExampleGreetingConfiguration.javafilepackage org.acme.config; import io.smallrye.config.ConfigMapping; import io.smallrye.config.WithDefault; import java.util.List; import java.util.Optional; @ConfigMapping(prefix = "greeting") public interface GreetingConfiguration { String message(); @WithDefault("!") String suffix(); Optional<String> name(); ContentConfig content(); interface ContentConfig { Integer prizeAmount(); List<String> recipients(); } }Note: The method name of the
ContentConfiginterface iscontent. To ensure that you bind the properties to the correct interface, when you define configuration properties for this class, usecontentin the prefix. In doing so, you can also prevent property name conflicts and unexpected application behavior. -
Define the
greeting.content.prize-amountandgreeting.content.recipientsconfiguration properties in yourapplication.propertiesfile.The following example shows the properties defined for the
GreetingConfigurationinstance and theContentConfiginterface:Exampleapplication.propertiesfilegreeting.message=hello greeting.name=quarkus greeting.content.prize-amount=10 greeting.content.recipients=Jane,John -
Instead of the three
@ConfigPropertyfield annotations, inject theGreetingConfigurationinstance into theGreetingResourceclass by using the@Injectannotation, as outlined in the following example. Also, you must update the message string that the/greetingendpoint returns with the values that you set for the newgreeting.content.prize-amountandgreeting.content.recipientsproperties that you added.ExampleGreetingResource.javafilepackage org.acme.config; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import jakarta.inject.Inject; @Path("/greeting") public class GreetingResource { @Inject GreetingConfiguration config; @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return config.message() + " " + config.name().orElse("world") + config.suffix() + "\n" + config.content().recipients() + " receive total of candies: " + config.content().prizeAmount(); } } -
Compile and start your application in development mode:
./mvnw quarkus:devImportant: If you do not provide values for the class properties, the application fails to compile and you receive a
jakarta.enterprise.inject.spi.DeploymentExceptionexception that indicates a missing value. This does not apply toOptionalfields and fields with a default value. -
To verify that the endpoint returns the message, open a new terminal window and enter the following command:
curl http://localhost:8080/greetingA message displays, containing two lines of output. The first line displays the greeting, and the second line reports the recipients of the prize together with the prize amount, as follows:
hello quarkus! [Jane, John] receive total of candies: 10 -
To stop the application, press Ctrl+C.
|
Note:
You can annotate classes that are annotated with
Your project must include the |
Accessing the configuration programmatically
You can define a method in your code to retrieve the values of the configuration properties in your application. In doing so, you can dynamically look up configuration property values or retrieve configuration property values from classes that are either CDI beans or Jakarta REST (formerly known as JAX-RS) resources.
You can access the configuration by using the org.eclipse.microprofile.config.ConfigProvider.getConfig() method.
The getValue() method of the config object returns the values of the configuration properties.
-
You have a Quarkus Maven project.
-
Use a method to access the value of a configuration property of any class or object in your application code. Depending on whether or not the value that you want to retrieve is set in a configuration source in your project, you can use one of the following methods:
-
To access the value of a property that is set in a configuration source in your project, for example, in the
application.propertiesfile, use thegetValue()method:String <variable-name> = ConfigProvider.getConfig().getValue("<property-name>", <data-type-class-name>.class);For example, to retrieve the value of the
greeting.messageproperty that has the data typeString, and is assigned to themessagevariable in your code, use the following syntax:String message = ConfigProvider.getConfig().getValue("greeting.message",String.class); -
When you want to retrieve a value that is optional or default and might not be defined in your
application.propertiesfile or another configuration source in your application, use thegetOptionalValue()method:Optional<String> <variable-name> = ConfigProvider.getConfig().getOptionalValue("<property-name>", <data-type-class-name>.class);For example, to retrieve the value of the
greeting.nameproperty that is optional, has the data typeString, and is assigned to thenamevariable in your code, use the following syntax:Optional<String> name = ConfigProvider.getConfig().getOptionalValue("greeting.name", String.class);
-
The following snippet shows a variant of the aforementioned GreetingResource class by using the programmatic access to the configuration:
src/main/java/org/acme/config/GreetingResource.javapackage org.acme.config;
import java.util.Optional;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Path("/greeting")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
Config config = ConfigProvider.getConfig();
String message = config.getValue("greeting.message", String.class);
String suffix = config.getOptionalValue("greeting.suffix", String.class).orElse("!");
Optional<String> name = config.getOptionalValue("greeting.name", String.class);
return message + " " + name.orElse("world") + suffix;
}
}
Property expressions
You can combine property references and text strings into property expressions and use them as values in your IBM Enterprise Build of Quarkus configuration.
Like variables, property expressions substitute configuration values dynamically, helping you avoid hard-coded values.
You can reference a property defined in one configuration source from another source.
IBM Enterprise Build of Quarkus resolves a property expression when it reads the configuration property:
-
At build time, if the property is read at build time
-
At runtime, if the property is read at runtime
If a property expression cannot be resolved and does not include a default value, IBM Enterprise Build of Quarkus throws a NoSuchElementException.
Example usage of property expressions
To achieve flexibility when you configure your Quarkus application, you can use property expressions as shown in the following examples.
-
Substituting the value of a configuration property:
To avoid hardcoding property values in your configuration, you can use a property expression. Use the
${<property_name>}syntax to write an expression that references a configuration property, as shown in the following example:Exampleapplication.propertiesfileremote.host=quarkus.io callable.url=https://${remote.host}/The value of the
callable.urlproperty resolves tohttps://quarkus.io/. -
Setting a property value that is specific to a particular configuration profile:
In the following example, the
%devconfiguration profile and the default configuration profile are set to use data source connection URLs with different host addresses.Exampleapplication.propertiesfile%dev.quarkus.datasource.jdbc.url=jdbc:mysql://localhost:3306/mydatabase?useSSL=false quarkus.datasource.jdbc.url=jdbc:mysql://remotehost:3306/mydatabase?useSSL=falseDepending on the configuration profile used to start your application, your data source driver uses the database URL that you set for the profile.
You can achieve the same result in a simplified way by setting a different value for the custom
application.serverproperty for each configuration profile. Then, you can reference the property in the database connection URL of your application, as shown in the following example:Exampleapplication.propertiesfile%dev.application.server=localhost application.server=remotehost quarkus.datasource.jdbc.url=jdbc:mysql://${application.server}:3306/mydatabase?useSSL=falseThe
application.serverproperty resolves to the appropriate value depending on the profile that you choose when you run your application. -
Setting a default value of a property expression:
You can define a default value for a property expression. Quarkus uses the default value if the value of the property that is required to expand the expression is not resolved from any of your configuration sources. You can set a default value for an expression by using the following syntax:
${<property_name>:<default_value>}In the following example, the property expression in the data source URL uses
mysql.db.serveras the default value of theapplication.serverproperty:Exampleapplication.propertiesfilequarkus.datasource.jdbc.url=jdbc:mysql://${application.server:mysql.db.server}:3306/mydatabase?useSSL=false -
Nesting property expressions:
You can compose property expressions by nesting a property expression inside another property expression. When nested property expressions are expanded, the inner expression is expanded first. You can use the following syntax for nesting property expressions:
${<outer_property_name>${<inner_property_name>}} -
Combining multiple property expressions:
You can join two or more property expressions together by using the following syntax:
${<first_property_name>}${<second_property_name>} -
Combining property expressions with environment variables:
You can use property expressions to substitute the values of environment variables. The expression in the following example substitutes the value that is set for the
HOSTenvironment variable as the value of theapplication.hostproperty:Exampleapplication.propertiesfileremote.host=quarkus.io application.host=${HOST:${remote.host}}
When the HOST environment variable is not set, the application.host property uses the value of the remote.host property as the default.
Using configuration profiles
You can use configuration profiles to tailor application behavior for different environments. With profiles, you can define multiple sets of configuration values and activate a specific set at runtime.
IBM Enterprise Build of Quarkus includes the following default configuration profiles:
-
dev: Activated when running in development mode.
-
test: Activated when running tests.
-
prod: Activated by default when not running in development or test modes.
|
Note: You can also define and activate custom configuration profiles. To define profile-specific configuration, you can:
To activate a custom profile, set the For more information, see Setting a custom configuration profile. |
-
You have created a Quarkus Maven project.
-
Open the
application.propertiesfile in thesrc/main/resourcesdirectory of your project. -
Add profile-specific configuration using one of the following approaches:
-
Add a property to your properties file and prefix it with a profile name nested between
%and., such as%dev.,%test., or%prod.. For example:%dev.quarkus.datasource.username=devuser %prod.quarkus.datasource.username=produser -
Alternatively, create a profile-specific configuration file such as
application-dev.properties,application-test.properties, orapplication-prod.propertiesto contain the profile-specific values.Exampleapplication-dev.propertiesquarkus.datasource.username=devuser
-
-
Activate a profile at runtime by setting the
quarkus.profileconfiguration option as a system property or environment variable:$ ./mvnw package -Dquarkus.profile=<profile>Replace
<profile>with one or more comma-separated profile names, such asdev,test, orprod.
|
Note:
You can also configure profile-aware files, where the properties for a specific profile are defined in an
|
Setting a custom configuration profile
You can create as many configuration profiles as you want. You can have multiple configurations in the same file and you can select a configuration by using a profile name.
-
To set a custom profile, create a configuration property with the profile name in the
application.propertiesfile, where<property_name>is the name of the property,<value>is the property value, and<profile>is the name of a profile:Create a configuration property%<profile>.<property_name>=<value>In the following example configuration, the value of
quarkus.http.portis9090by default, and becomes8181when thedevprofile is activated:Example configurationquarkus.http.port=9090 %dev.quarkus.http.port=8181 -
Use one of the following methods to enable a profile:
-
Set the
quarkus.profilesystem property.-
To enable a profile by using the
quarkus.profilesystem property, enter the following command:Enable a profile by usingquarkus.profilepropertymvn -Dquarkus.profile=<value> quarkus:dev
-
-
Set the
QUARKUS_PROFILEenvironment variable.-
To enable profile by using an environment variable, enter the following command:
Enable a profile by using an environment variableexport QUARKUS_PROFILE=<profile>Note: The system property value takes precedence over the environment variable value.
-
-
-
To repackage the application and change the profile, enter the following command:
Change a profile./mvnw package -Dquarkus.profile=<profile> java -jar target/quarkus-app/quarkus-run.jarThe following example shows a command that activates the
prod-awsprofile:Example command to activate a profile./mvnw package -Dquarkus.profile=prod-aws java -jar target/quarkus-app/quarkus-run.jar
|
Note:
The default Quarkus application runtime profile is set to the profile that is used to build the application.
IBM Enterprise Build of Quarkus automatically selects a profile depending on your environment mode.
For example, when your application is running as a JAR, Quarkus is in |
Setting custom configuration sources
By default, a Quarkus application reads properties from the application.properties file in the src/main/resources subdirectory of your project.
With Quarkus, you can load application configuration properties from other sources according to the MicroProfile Config specification for externalized configuration.
You can enable your application to load configuration properties from other sources by defining classes that implement the org.eclipse.microprofile.config.spi.ConfigSource and the org.eclipse.microprofile.config.spi.ConfigSourceProvider interfaces.
This procedure demonstrates how you can implement a custom configuration source in your Quarkus project.
You have the Quarkus config-quickstart project.
|
Note:
For a completed example of that project, download the
Quarkus Quickstarts archive or clone the Quarkus Quickstarts Git repository and go to the |
-
In your project, create a new class that implements the
org.eclipse.microprofile.config.spi.ConfigSourceProviderinterface. Override thegetConfigSources()method to return a list of your customConfigSourceobjects.Exampleorg.acme.config.InMemoryConfigSourceProviderpackage org.acme.config; import org.eclipse.microprofile.config.spi.ConfigSource; import org.eclipse.microprofile.config.spi.ConfigSourceProvider; import java.util.List; public class InMemoryConfigSourceProvider implements ConfigSourceProvider { @Override public Iterable<ConfigSource> getConfigSources(ClassLoader classLoader) { return List.of(new InMemoryConfigSource()); } } -
To define your custom configuration source, create an
InMemoryConfigSourceclass that implements theorg.eclipse.microprofile.config.spi.ConfigSourceinterface:Exampleorg.acme.config.InMemoryConfigSourcepackage org.acme.config; import org.eclipse.microprofile.config.spi.ConfigSource; import java.util.HashMap; import java.util.Map; import java.util.Set; public class InMemoryConfigSource implements ConfigSource { private static final Map<String, String> configuration = new HashMap<>(); static { configuration.put("my.prop", "1234"); } @Override public int getOrdinal() { (1) return 275; } @Override public Set<String> getPropertyNames() { return configuration.keySet(); } @Override public String getValue(final String propertyName) { return configuration.get(propertyName); } @Override public String getName() { return InMemoryConfigSource.class.getSimpleName(); } }1 The getOrdinal()method returns the priority of theConfigSourceclass. Therefore, when multiple configuration sources define the same property, Quarkus can select the appropriate value as defined by theConfigSourceclass with the highest priority. -
In the
src/main/resources/META-INF/services/subdirectory of your project, create a file namedorg.eclipse.microprofile.config.spi.ConfigSourceProviderand enter the fully-qualified name of the class that implements theConfigSourceProviderin the file that you created:Exampleorg.eclipse.microprofile.config.spi.ConfigSourceProviderfile:org.acme.config.InMemoryConfigSourceProviderTo ensure that the
ConfigSourceProviderthat you created is registered and installed when you compile and start your application, you must complete the previous step. -
Edit the
GreetingResource.javafile in your project to add the following update:@ConfigProperty(name="my.prop") int value; -
In the
GreetingResource.javafile, extend thehellomethod to use the new property:@GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return message + " " + name.orElse("world") + " " + value; } -
Compile and start your application in development mode:
./mvnw quarkus:dev -
Open a terminal window and send a request to the
/greetingendpoint:curl http://localhost:8080/greeting -
Verify that your application has read the custom configuration and returned the expected message:
hello world 1234
Using custom configuration converters as configuration values
You can store custom types as configuration values by implementing org.eclipse.microprofile.config.spi.Converter<T> and adding its fully qualified class name into the META-INF/services/org.eclipse.microprofile.config.spi.Converter file.
By using converters, you can transform the string representation of a value into an object.
You have created the Quarkus config-quickstart project.
-
In the
org.acme.configpackage, create theorg.acme.config.MyCustomValueclass with the following content:Example of custom configuration valuepackage org.acme.config; public class MyCustomValue { private final int value; public MyCustomValue(Integer value) { this.value = value; } public int value() { return value; } } -
Implement the converter class to override the convert method to produce a
MyCustomValueinstance.Example implementation of converter classpackage org.acme.config; import org.eclipse.microprofile.config.spi.Converter; public class MyCustomValueConverter implements Converter<MyCustomValue> { @Override public MyCustomValue convert(String value) { return new MyCustomValue(Integer.valueOf(value)); } } -
Add the fully-qualified class name of the converter,
org.acme.config.MyCustomValueConverter, to yourMETA-INF/services/org.eclipse.microprofile.config.spi.Converterservice file. -
In the
GreetingResource.javafile, inject theMyCustomValueproperty:@ConfigProperty(name="custom") MyCustomValue value; -
Edit the
hellomethod to use this value:@GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return message + " " + name.orElse("world") + " - " + value.value(); } -
In the
application.propertiesfile, add the string representation to be converted:custom=1234 -
To compile and start your application in development mode, enter the following command:
./mvnw quarkus:dev -
To verify that the
/greetingendpoint returns the expected message, open a terminal window and enter the following command:curl http://localhost:8080/greeting -
When your application successfully reads the custom configuration, the command returns the following response:
hello world - 1234Note: Your custom converter class must be
publicand must have apublicno-argument constructor. Your custom converter class cannot beabstract.
Setting custom converters priority
The default priority for all Quarkus core converters is 200.
For all other converters, the default priority is 100.
You can increase the priority of your custom converters by using the jakarta.annotation.Priority annotation.
The following procedure demonstrates an implementation of a custom converter, AnotherCustomValueConverter, which has a priority of 150.
This takes precedence over MyCustomValueConverter from the previous section, which has a default priority of 100.
-
You have created the Quarkus
config-quickstartproject. -
You have created a custom configuration converter for your application.
-
Set a priority for your custom converter by annotating the class with the
@Priorityannotation and passing it a priority value. In the following example, the priority value is set to150.ExampleAnotherCustomValueConverter.javafilepackage org.acme.config; import jakarta.annotation.Priority; import org.eclipse.microprofile.config.spi.Converter; @Priority(150) public class AnotherCustomValueConverter implements Converter<MyCustomValue> { @Override public MyCustomValue convert(String value) { return new MyCustomValue(Integer.valueOf(value)); } } -
Create a file named
org.eclipse.microprofile.config.spi.Converterin thesrc/main/resources/META-INF/services/subdirectory of your project, and enter the fully qualified name of the class that implements theConverterin the file that you created:Exampleorg.eclipse.microprofile.config.spi.Converterfileorg.acme.config.AnotherCustomValueConverterYou must complete the previous step to ensure that the
Converteryou created is registered and installed when you compile and start your application.
After you complete the required configuration, the next step is to compile and package your Quarkus application. For more information and examples, see the compiling and packaging sections of the Getting started with Quarkus guide.