The Spring way

The developers that work with Spring know very well how easy is to separate the configuration of the application from the code. In Spring there is an application.properties file in the resources that contains the main configuration of the application. The properties can be used in the code injecting fields with the @Value annotation or, better, injecting a properties class with @ConfigurationProperties (only SpringBoot).

You can find more details for Spring here: 24. Externalized Configuration

Java EE before MicroProfile

In Java EE the procedure was more complicated. To store properties in a file the solutions were the following: StackOverflow - Where to place and how to read configuration resource files in servlet based application?

Java EE with MicroProfile ConfigFeature

MicroProfile introduces the Config Feature. Thanks to this project Java EE applications can use external configuration files with ease.

Tutorial with Java EE 8 (Payara)

For our example we use Payara but you can use other Java EE servers.

pom.xml

<dependencies>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>8.0</version>
        <scope>provided</scope>
    </dependency>
    
        <!-- MicroProfile Config 1.3 API -->

    <dependency>
        <groupId>org.eclipse.microprofile.config</groupId>
        <artifactId>microprofile-config-api</artifactId>
        <version>1.3</version>
         <scope>provided</scope>
    </dependency>
</dependencies>

In our pom we have only 2 dependencies: Java EE 8 and MicroProfile Config API. The implementations of the these dependencies are already integrated in Payara.

sources structure

./src
├── main
│   ├── java
│   │   └── io
│   │       └── javademo
│   │           └── micro
│   │               ├── ApplicationConfig.java
│   │               └── api
│   │                   └── ExampleResource.java
│   └── resources
│       └── META-INF
│           ├── beans.xml
│           └── microprofile-config.properties

beans.xml

It’s important to don’t forget the beans.xml file in WEB-INF or META-INF. The presence of this empty file enables CDI. Without it @Inject will not work.

microprofile-config.properties

This file contains the properties that we want to inject. In our case we add simple:

name=marco

ApplicationConfig.java

This is the entry point of the REST services:

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("api")
public class ApplicationConfig extends Application {
}

ExampleResource.java

This file define the REST endpoint that returns the name defined in the properties file:

package io.javademo.micro.api;

import org.eclipse.microprofile.config.inject.ConfigProperty;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

// with @Path we define the url of the endpoint:
// http://javademo.io/api/example
@Path("example")
public class ExampleResource {

    // inject is required to import the property
    // to work beans.xml has to be present in webapp/WEB-INF
    @Inject
    // the property name has to match the propety in 
    // META-INF/microprofile-config.properties
    @ConfigProperty(name="name", defaultValue = "(Name not present)")
    private String name;

    @Inject
    @ConfigProperty(name="country", defaultValue = "(Country not present)")
    private String country;

    @GET
    public String hello() {
        return String.format("Name: %s, Country: %s", name, country);
    }
}

To inject the field we use the CDI annotation @Inject. To define which property is injected we @ConfigProperty that comes with MicroProfile:

@ConfigProperty(name="name", defaultValue = "(Name not present)")
private String name;

If case the property is not found in the properties file, the defaultValue is used to assign the field.

Use of Config

The same result can be achieved injecting the Config object:

@Inject
private Config config;

config.getValue("name", String.class);

REST answer

The result:

Name: marco, Country: (Country not present)