Chapter 7. Using a BOM

To explicitly specify the Thorntail fractions your application uses, instead of relying on auto-detection, Thorntail includes a set of BOMs (bill of materials) which you can use instead of having to track and update Maven artifact versions in several places.

7.1. Thorntail product BOM types

Thorntail is described as just enough app-server, which means it consists of multiple pieces. Your application includes only the pieces it needs.

When using the Thorntail product, you can specify the following Maven BOMs:

bom
All fractions available in the product.
bom-certified
All community fractions that have been certified against the product. Any fraction used from bom-certified is unsupported.

7.2. Specifying a BOM for in your application

Importing a specific BOM in the pom.xml file in your application allows you to track all your application dependencies in one place.

Note

One shortcoming of importing a Maven BOM import is that it does not handle the configuration on the level of <pluginManagement>. When you use the Thorntail Maven Plugin, you must specify the version of the plugin to use.

Thanks to the property you use in your pom.xml file, you can easily ensure that your plugin usage matches the release of Thorntail that you are targeting with the BOM import.

<plugins>
  <plugin>
    <groupId>io.thorntail</groupId>
    <artifactId>thorntail-maven-plugin</artifactId>
    <version>${version.thorntail}</version>
      ...
  </plugin>
</plugins>

Prerequisites

  • Your application as a Maven-based project with a pom.xml file.

Procedure

  1. Include a bom artifact in your pom.xml.

    Tracking the current version of Thorntail through a property in your pom.xml is recommended.

    <properties>
      <version.thorntail>2.4.0.Final-redhat-00013</version.thorntail>
    </properties>

    Import BOMs in the <dependencyManagement> section. Specify the <type>pom</type> and <scope>import</scope>.

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>io.thorntail</groupId>
          <artifactId>bom</artifactId>
          <version>${version.thorntail}</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>

    In the example above, the bom artifact is imported to ensure that only stable fractions are available.

    By including the BOMs of your choice in the <dependencyManagement> section, you have:

    • Provided version-management for any Thorntail artifacts you subsequently choose to use.
    • Provided support to your IDE for auto-completing known artifacts when you edit your the pom.xml file of your application.
  2. Include Thorntail dependencies.

    Even though you imported the Thorntail BOMs in the <dependencyManagement> section, your application still has no dependencies on Thorntail artifacts.

    To include Thorntail artifact dependencies based on the capabilities your application, enter the relevant artifacts as <dependency> elements:

    Note

    You do not have to specify the version of the artifacts because the BOM imported in <dependencyManagement> handles that.

    <dependencies>
      <dependency>
        <groupId>io.thorntail</groupId>
        <artifactId>jaxrs</artifactId>
      </dependency>
      <dependency>
        <groupId>io.thorntail</groupId>
        <artifactId>datasources</artifactId>
      </dependency>
    </dependencies>

    In the example above, we include explicit dependencies on the jaxrs and datasources fractions, which will provide transitive inclusion of others, for example undertow.

7.3. Logging

7.3.1. Enabling logging

Each Thorntail fraction is dependent on the Logging fraction, which means that if you use any Thorntail fraction in your application, logging is automatically enabled on the INFO level and higher. If you want to enable logging explicitly, add the Logging fraction to the POM file of your application.

Prerequisites

  • A Maven-based application

Procedure

  1. Find the <dependencies> section in the pom.xml file of your application. Verify it contains the following coordinates. If it does not, add them.

    <dependency>
      <groupId>io.thorntail</groupId>
      <artifactId>logging</artifactId>
    </dependency>
  2. If you want to log messages of a level other than INFO, launch the application while specifying the thorntail.logging system property:

    $ mvn thorntail:run -Dthorntail.logging=FINE

    See the org.wildfly.swarm.config.logging.Level class for the list of available levels.

7.3.2. Logging to a file

In addition to the console logging, you can save the logs of your application in a file. Typically, deployments use rotating logs to save disk space.

In Thorntail, logging is configured using system properties. Even though it is possible to use the -Dproperty=value syntax when launching your application, it is strongly recommended to configure file logging using the YAML profile files.

Prerequisites
Procedure
  1. Open a YAML profile file of your choice. If you do not know which one to use, open project-defaults.yml in the src/main/resources directory in your application sources. In the YAML file, add the following section:

    thorntail:
      logging:
  2. Configure a formatter (optional). The following formatters are configured by default:

    PATTERN
    Useful for logging into a file.
    COLOR_PATTERN
    Color output. Useful for logging to the console.

    To configure a custom formatter, add a new formatter with a pattern of your choice in the logging section. In this example, it is called LOG_FORMATTER:

    pattern-formatters:
      LOG_FORMATTER:
        pattern: "%p [%c] %s%e%n"
  3. Configure a file handler to use with the loggers. This example shows the configuration of a periodic rotating file handler. Under logging, add a periodic-rotating-file-handlers section with a new handler.

    periodic-rotating-file-handlers:
      FILE:
        file:
          path: target/MY_APP_NAME.log
        suffix: .yyyy-MM-dd
        named-formatter: LOG_FORMATTER
        level: INFO

    Here, a new handler named FILE is created, logging events of the INFO level and higher. It logs in the target directory, and each log file is named MY_APP_NAME.log with the suffix .yyyy-MM-dd. Thorntail automatically parses the log rotation period from the suffix, so ensure you use a format compatible with the java.text.SimpleDateFormat class.

  4. Configure the root logger.

    The root logger is by default configured to use the CONSOLE handler only. Under logging, add a root-logger section with the handlers you wish to use:

    root-logger:
      handlers:
      - CONSOLE
      - FILE

    Here, the FILE handler from the previous step is used, along with the default console handler.

Below, you can see the complete logging configuration section:

The logging section in a YAML configuration profile

thorntail:
  logging:
    pattern-formatters:
      LOG_FORMATTER:
        pattern: "CUSTOM LOG FORMAT %p [%c] %s%e%n"
    periodic-rotating-file-handlers:
      FILE:
        file:
          path: path/to/your/file.log
        suffix: .yyyy-MM-dd
        named-formatter: LOG_FORMATTER
    root-logger:
      handlers:
      - CONSOLE
      - FILE

7.4. Configuring a Thorntail application

You can configure numerous options with applications built with Thorntail. For most options, reasonable defaults are already applied, so you do not have to change any options unless you explicitly want to.

This reference is a complete list of all configurable items, grouped by the fraction that introduces them. Only the items related to the fractions that your application uses are relevant to you.

7.4.1. System properties

Using system properties for configuring your application is advantageous for experimenting, debugging, and other short-term activities.

7.4.1.1. Commonly used system properties

This is a non-exhaustive list of system properties you are likely to use in your application:

General system properties

thorntail.bind.address

The interface to bind servers

Default

0.0.0.0

thorntail.port.offset

The global port adjustment

Default

0

thorntail.context.path

The context path for the deployed application

Default

/

thorntail.http.port

The port for the HTTP server

Default

8080

thorntail.https.port

The port for the HTTPS server

Default

8483

thorntail.debug.port

If provided, the Thorntail process will pause for debugging on the given port.

This option is only available when running an Arquillian test or starting the application using the mvn thorntail:run command, not when executing a JAR file. The JAR file execution requires normal Java debug agent parameters.

Default

 

Datasource-related system properties

With JDBC driver autodetection, use the following properties to configure the datasource:

thorntail.ds.name

The name of the datasource

Default

ExampleDS

thorntail.ds.username

The user name to access the database

Default

driver-specific

thorntail.ds.password

The password to access the database

Default

driver-specific

thorntail.ds.connection.url

The JDBC connection URL

Default

driver-specific

Note

For a full set of available properties, see the documentation for each fraction and the javadocs on class SwarmProperties.java

7.4.1.2. Application configuration using system properties

Configuration properties are presented using dotted notation, and are suitable for use as Java system property names, which your application consumes through explicit setting in the Maven plugin configuration, or through the command line when your application is being executed.

Any property that has the KEY parameter in its name indicates that you must supply a key or identifier in that segment of the name.

Configuration of items with the KEY parameter

A configuration item documented as thorntail.undertow.servers.KEY.default-host indicates that the configuration applies to a particular named server.

In practical usage, the property would be, for example, thorntail.undertow.servers.default.default-host for a server known as default.

7.4.1.3. Setting system properties using the Maven plugin

Setting properties using the Maven plugin is useful for temporarily changing a configuration item for a single execution of your Thorntail application.

Note

Even though the configuration in the POM file of your application is persistent, it is not recommended to use it for long-term configuration of your application. Instead, use the YAML configuration files.

If you want to set explicit configuration values as defaults through the Maven plugin, add a <properties> section to the <configuration> block of the plugin in the pom.xml file in your application.

Prerequisites
  • Your Thorntail-based application with a POM file
Procedure
  1. In the POM file of your application, locate the configuration you want to modify.
  2. Insert a block with configuration of the io.thorntail:thorntail-maven-plugin artifact, for example:

    <build>
      <plugins>
        <plugin>
          <groupId>io.thorntail</groupId>
          <artifactId>thorntail-maven-plugin</artifactId>
          <version>2.4.0.Final-redhat-00013</version>
          <configuration>
            <properties>
              <thorntail.bind.address>127.0.0.1</thorntail.bind.address>
              <java.net.preferIPv4Stack>true</java.net.preferIPv4Stack>
            </properties>
          </configuration>
        </plugin>
      </plugins>
    </build>

    In the example above, the thorntail.bind.address property is set to 127.0.0.1 and the java.net.preferIPv4Stack property is set to true.

7.4.1.4. Setting system properties using the command line

Setting properties using the Maven plugin is useful for temporarily changing a configuration item for a single execution of your Thorntail application.

You can customize an environment-specific setting or experiment with configuration items before setting them in a YAML configuration file.

To use a property on the command line, pass it as a command-line parameter to the Java binary:

Prerequisites
  • A JAR file with your application
Procedure
  1. In a terminal application, navigate to the directory with your application JAR file.
  2. Execute your application JAR file using the Java binary and specify the property and its value:

    $ java -Dthorntail.bind.address=127.0.0.1 -jar myapp-thorntail.jar

    In this example, you assing the value 127.0.0.1 to the property called thorntail.bind.address.

7.4.1.5. Specifying JDBC drivers for hollow JARs

When executing a hollow JAR, you can specify a JDBC Driver JAR using the thorntail.classpath property. This way, you do not need to package the driver in the hollow JAR.

The thorntail.classpath property accepts one or more paths to JAR files separated by ; (a semicolon). The specified JAR files are added to the classpath of the application.

Prerequisites
  • A JAR file with your application
Procedure
  1. In a terminal application, navigate to the directory with your application JAR file.
  2. Execute your application JAR file using the Java binary and specify the JDBC driver:

    $ java -Dthorntail.classpath=./h2-1.4.196.jar -jar microprofile-jpa-hollow-thorntail.jar example-jpa-jaxrs-cdi.war

7.4.2. Environment Variables

Use environment variables to configure your application or override values stored in YAML files.

7.4.2.1. Application configuration using environment variables

Use environment variables to configure your application in various deployments—​especially in a containerized environment, such as Docker.

Example 7.1. Environment variables configuration

A property documented as thorntail.undertow.servers.KEY.default-host translates to the following environment variable (substituting the KEY segment with the default identifier):

export THORNTAIL.UNDERTOW.SERVERS.DEFAULT.DEFAULT_DASH_HOST=<myhost>

Unlike other configuration options, properties defined as environment variables in Linux-based containers do not allow defining non-alphanumeric characters like dot (.), dash/hyphen (-) or any other characters not in the [A-Za-z0-9_] range. Many configuration properties in Thorntail contain these characters, so you must follow these rules when defining the environment variables in the following environments:

Linux-based container rules

  • It is a naming convention that all environment properties are defined using uppercase letters. For example, define the serveraddress property as SERVERADDRESS.
  • All the dot (.) characters must be replaced with underscore (_). For example, define the thorntail.bind.address=127.0.0.1 property as THORNTAIL_BIND_ADDRESS=127.0.0.1.
  • All dash/hyphen (-) characters must be replaced with the _DASH_ string. For example, define the thorntail.data-sources.foo.url=<url> property as THORNTAIL_DATA_DASH_SOURCES_FOO_URL=<url>.
  • If the property name contains underscores, all underscore (_) characters must be replaced with the _UNDERSCORE_ string. For example, define the thorntail.data_sources.foo.url=<url> property as THORNTAIL_DATA_UNDERSCORE_SOURCES_FOO_URL=<url>.

Example 7.2. An example data source configuration

System property

-Dthorntail.datasources.data-sources.devwf.connection-url= jdbc:postgresql://localhost:5432/sampledb

Env. variable

THORNTAIL_DATASOURCES_DATA_DASH_SOURCES_DEVWF_CONNECTION_DASH_URL= 'jdbc:postgresql://localhost:5432/sampledb'

System property

-Dthorntail.datasources.data-sources.devwf.driver-name=postgresql

Env. variable

THORNTAIL_DATASOURCES_DATA_DASH_SOURCES_DEVWF_DRIVER_DASH_NAME='postgresql'

System property

-Dthorntail.datasources.data-sources.devwf.jndiname=java:/jboss/datasources/devwf

Env. variable

THORNTAIL_DATASOURCES_DATA_DASH_SOURCES_DEVWF_JNDI_DASH_NAME='java:/jboss/datasources/devwf'

System property

-Dthorntail.datasources.data-sources.devwf.user-name=postgres

Env. variable

THORNTAIL_DATASOURCES_DATA_DASH_SOURCES_DEVWF_USER_DASH_NAME='postgres'

System property

-Dthorntail.datasources.data-sources.devwf.password=admin

Env. variable

THORNTAIL_DATASOURCES_DATA_DASH_SOURCES_DEVWF_PASSWORD='admin'

7.4.3. YAML files

YAML is the preferred method for long-term configuration of your application. In addition to that, the YAML strategy provides grouping of environment-specific configurations, which you can selectively enable when executing the application.

7.4.3.1. The general YAML file format

The Thorntail configuration item names correspond to the YAML configuration structure.

Example 7.3. YAML configuration

For example, a configuration item documented as thorntail.undertow.servers.KEY.default-host translates to the following YAML structure, substituting the KEY segment with the default identifier:

thorntail:
  undertow:
    servers:
      default:
        default-host: <myhost>

7.4.3.2. Default Thorntail YAML Files

By default, Thorntail looks up permanent configuration in files with specific names to put on the classpath.

project-defaults.yml

If the original .war file with your application contains a file named project-defaults.yml, that file represents the defaults applied over the absolute defaults that Thorntail provides.

Other default file names

In addition to the project-defaults.yml file, you can provide specific configuration files using the -S <name> command-line option. The specified files are loaded, in the order you provided them, before project-defaults.yml. A name provided in the -S <name> argument specifies the project-<name>.yml file on your classpath.

Example 7.4. Specifying configuration files on the command line

Consider the following application execution:

$ java -jar myapp-thorntail.jar -Stesting -Scloud

The following YAML files are loaded, in this order. The first file containing a given configuration item takes precedence over others:

  1. project-testing.yml
  2. project-cloud.yml
  3. project-defaults.yml

7.4.3.3. Non-default Thorntail YAML configuration files

In addition to default configuration files for your Thorntail-based application, you can specify YAML files outside of your application. Use the -s <path> command-line option to load the desired file.

Both the -s <path> and -S <name> command-line options can be used at the same time, but files specified using the -s <path> option take precedence over YAML files contained in your application.

Example 7.5. Specifying configuration files inside and outside of the application

Consider the following application execution:

$ java -jar myapp-thorntail.jar -s/home/app/openshift.yml -Scloud -Stesting

The following YAML files are loaded, in this order:

  1. /home/app/openshift.yml
  2. project-cloud.yml
  3. project-testing.yml
  4. project-defaults.yml

The same order of preference is applied even if you invoke the application as follows:

$ java -jar myapp-thorntail.jar -Scloud -Stesting -s/home/app/openshift.yml