Server configuration overview

The Open Liberty server config is made up of one mandatory file, the server.xml file, and a set of optional additional files. The server.xml is the only mandatory config file. The only requirements for the server.xml file are that it must be well formed XML and the root element is server. When processing the server.xml file, any elements or attributes that are not understood are simply ignored. The default server.xml might look like the following example:

<server description="new server">
    <featureManager>
        <feature>jsp-2.3</feature>
    </featureManager>
    <httpEndpoint id="defaultHttpEndpoint"
                  httpPort="9080"
                  httpsPort="9443" />
    <applicationManager autoExpand="true"/>
</server>

This example server.xml configures the server to support Java Server Pages 2.3, to listen to incoming traffic to localhost on port 9080, and to automatically expand WAR files when they are deployed.

The server.xml is described in more detail below. When discussing config for Open Liberty, the term "server config" can be used to refer to all of the files that make up the server config, or specifically to the config held in XML files; it is usually clear in context and, if not, the phrase "server XML config" might be used to clarify. The next few sections describe each of the config files in the order they are processed.

server.env

The server.env files are optional but, when present, are read by the bin/server script and specify environment variables primarily used to influence the behavior of the bin/server script. server.env files are read from the following locations in order:

  • ${wlp.install.dir}/etc/

  • ${wlp.user.dir}/shared/

  • ${server.config.dir}/

If the same property is set in multiple locations the last value found is used.

The most common use of this file is to set the following settings:

  • JAVA_HOME - indicates which JVM to use. If this is not set, the system default is used which often isn’t desired.

  • WLP_USER_DIR - indicates the location of the usr directory which contains the server config. This can only be set in the etc/server.env file because the other locations are relative to the usr directory.

  • WLP_OUTPUT_DIR - indicates where the server should write files to. By default, the server writes to the directory structure that the config is read from. However, in some secure profiles the server config needs to be read-only and so the server must write files to another location.

The server.env file format is in terms of KEY = value and does not support variable substitution. For example:

    JAVA_HOME=/opt/ibm/java
    WLP_USER_DIR=/opt/wlp-usr
Key values must not contain white space. The values are interpreted as literal so there is no need to escape spaces or other special characters.

jvm.options

The jvm.options files are optional but, when present, are read by the bin/server shell script to determine what options to use when launching the JVM for Open Liberty. The jvm.options files are read from the following locations in order:

  • ${wlp.user.dir}/shared/jvm.options

  • ${server.config.dir}/configDropins/defaults/

  • ${server.config.dir}/

  • ${server.config.dir}/configDropins/overrides/

If none of these files exist, the server script looks for a file in ${wlp.install.dir}/etc and uses that.

Common uses of jvm.options files include:

  • Setting JVM memory limits

  • Enabling Java Agents provided by monitoring products

  • Setting Java System Properties

The jvm.options file format uses one line per JVM option and does not support variable substitution. For example:

-Xmx512m
-Dmy.system.prop=This is the value.

There is no need to escape special characters, such as spaces.

The options are read and provided in order to the JVM. If you provide multiple options they are all seen by the JVM (most JVMs use the last option on the command line and ignore prior options). Certain options must not be put in the jvm.options file such as -jar.

bootstrap.properties

The bootstrap.properties file is optional but, when present, it is read during Open Liberty bootstrap to provide config for the earliest stages of the server start-up. It is read by the server much earlier than server.xml so it can affect the start-up and behavior of the Open Liberty kernel right from the start. The bootstrap.properties file is a simple Java properties file and is located in ${server.config.dir}. A common use of the bootstrap.properties file is to configure logging because it can affect logging behavior before the server.xml file is read.

The bootstrap.properties file supports a special property, bootstrap.include, which optionally specifies another properties file to also be read during the bootstrap stage. This include file could, for example, contain a common set of bootstrap properties to be used by multiple servers. Set the bootstrap.include to an absolute or relative file path.

server.xml

The most important config file is the server.xml file. It is a simple XML file format and the only requirement for the server to start is that the file is well-formed XML and has a root element called server. The exact elements supported by a server depend on which features the server is configured so unknown config is simply ignored.

Open Liberty uses a principle of configuration by exception, allowing for very succinct config files. The runtime environment operates from a set of built-in config default settings. You only specify config that overrides those default settings.

Server config files are loaded in the following order:

  • ${server.config.dir}/configDropins/defaults/

  • ${server.config.dir}/server.xml

  • ${server.config.dir}/configDropins/overrides/

The ${server.config.dir}/server.xml file must be present but the other files are optional. This allows a very flexible way to compose config by simply dropping server-formatted XML files into directories. Within the two configDropins directories the files are read in alphabetical order.

Variable substitution

You can parameterize server config using variables. When resolving variable names the following sources are consulted in increasing order of precedence:

  • server.xml default variable values

  • envrionment variables

  • bootstrap.properties

  • Java system properties

  • server.xml config

Variables are referenced using ${variableName} syntax. In server config, specify variables using the variable element:

<variable name="variableName" value="some.value" />

Default values, specified in server config, are only used if no other value can be found. They are specified using the variable element and the defaultValue attribute:

<variable name="variableName" defaultValue="some.default.value"/>

Environment variables can be accessed as variables. From 19.0.0.3, they can be accessed directly by referencing the environment variable name. If the variable cannot be resolved the following transformations on the environment variable name is tried:

  1. Replace all non-alpha num characters with _

  2. Change all characters to upper case.

If you enter ${my.env.var} in server.xml it will look for environment variables with the following names:

  1. my.env.var

  2. my_env_var

  3. MY_ENV_VAR

When using a Liberty release older than 19.0.0.3, environment variables can be accessed by adding env. to the start of the environment variable name:

<httpEndpoint id="defaultHttpEndpoint"
              host="${env.HOST}"
              httpPort="9080" />

Variable values are always interpreted as a String with simple type conversion. This can lead to situations where a list of ports (e.g. 80,443) is interpreted as a single string rather than as two port numbers. In this case, the variable substitution can be forced to split on the , using a list function. For example:

<mongo ports="${list(mongoPorts)}" hosts="${list(mongoHosts)}" />

Simple arithmetic is also supported for variables whose value is an integer. The left and right side of the operator can be a variable or a number; the operator can be one of +, -, *, / for example:

<variable name="one" value="1" />
<variable name="two" value="${one+1}" />
<variable name="three" value="${one+two}" />
<variable name="six" value="${two*three}" />
<variable name="five" value="${six-one}" />
<variable name="threeagain" value="${six/two}" />

There are a number of predefined variables:

  • wlp.install.dir - the location where the Liberty runtime is installed.

  • wlp.server.name - the name of the server.

  • wlp.user.dir - the location of the usr folder. Defaults to ${wlp.install.dir}/usr.

  • shared.app.dir - the location of shared applications. Defaults to ${wlp.user.dir}/shared/apps.

  • shared.config.dir - the directory that contains the server config. Defaults to ${wlp.user.dir}/shared/config.

  • shared.resource.dir - the location of shared resource files. Defaults to ${wlp.user.dir}/shared/resources.

  • server.config.dir - the directory that server config is stored in. Defaults to ${wlp.user.dir}/servers/${wlp.server.name}.

  • server.output.dir - the directory that the server writes the workarea, logs and other runtime generated files to. Defaults to ${server.config.dir}.

Config merging

The config can be made up of multiple files so it is possible, perhaps even likely, that two files provide the same config. In these situations the server config is merged using a set of simple rules. In Open Liberty, config is separated into singleton and factory config. Merging works differently for the two. Singleton config is used when configuring a single thing (e.g. logging); factory config is used when it is valid to configure multiple things, (e.g. an application or a data source).

Merging singleton config

For singleton config elements the config is merged. If two elements exist with different attributes both attributes are used. For example:

<server>
    <logging a="true" />
    <logging b="false" />
</server>

is treated as:

<server>
    <logging a="true" b="false" />
</server>

If the same attribute is specified twice then it is treated as a last instance wins. For example:

<server>
    <logging a="true" b="true"/>
    <logging b="false" />
</server>

is treated as:

<server>
    <logging a="true" b="false" />
</server>

In some cases, config is provided using child elements that take text. In these cases the config is merged by using all of the values specified. The most common scenario is configuring features. For example:

<server>
    <featureManager>
        <feature>servlet-4.0</feature>
    </featureManager>
    <featureManager>
        <feature>restConnector-2.0</feature>
    </featureManager>
</server>

is treated as:

<server>
    <featureManager>
        <feature>servlet-4.0</feature>
        <feature>restConnector-2.0</feature>
    </featureManager>
</server>

Merging factory config

Factory config merges use the same rules as singleton config but, because it is valid to configure the same element and mean two different logical objects, merging doesn’t happen just because the element names match. Instead each element is assumed to be configuring a distinct object. If the logical object is configured by two instances, the id attribute must be set on each of them to indicate they are the same thing. Variable substitution on an id is not supported.

The following example configures two applications. One is myapp.war and has a context root of myawesomeapp and the other is myapp2.war which has myapp2 as the context root:

<server>
    <webApplication id="app1" location="myapp.war" />
    <webApplication location="myapp2.war" />
    <webApplication id="app1" contextRoot="/myawesomeapp" />
</server>

Include processing

In addition to the default locations, additional config files can be brought in using the include element. When a server config file contains an include reference to another file, the server processes the contents of the referenced file as if they were included inline in place of the include element. In the following example, the server processes the contents of the other.xml file before processing the contents of the other2.xml file:

<server>
    <include location="other.xml" />
    <include location="other2.xml" />
</server>

By default, an include file must exist but, if the include file might not be present, the optional attribute can be set to true. For example:

<server>
    <include location="other.xml" optional="true" />
</server>

When including a file, you can specify the onConflict attribute to change the normal merge rules. The normal merge rules can be replaced to ignore (IGNORE) any conflicting config or to replace it (REPLACE).

<server>
    <include location="other.xml" onConflict="IGNORE" />
    <include location="other2.xml" onConflict="REPLACE" />
</server>

You can set the location attribute to a relative or absolute file path or to an HTTP URL.

Config references

Most configuration in Open Liberty is self-contained but it is often useful to be able to share config. A common example of this would be the JDBC driver config being shared by multiple data sources, or sharing the classloader for JDBC driver classes so the classes are visible both to the DataSource and to an application. Any factory config element defined as a direct child of the server element can be referred to.

A reference to config always uses the id attribute of the element being referred to. The config element making the reference uses an attribute that always ends with Ref. For example:

<server>
  <dataSource jndiName="jdbc/fred" jdbcDriverRef="myDriver" />
  <jdbcDriver id="myDriver" />
</server>

Dynamic updates

The server monitors the server XML config for updates and dynamically reloads when changes are detected. Changes to non-XML files (server.env, bootstrap.properties, and jvm.options) are not dynamic because they are only read at start-up. Any server XML config file on the local disk is monitored for updates every 500ms. Whether to check, and how often, can be configured. To configure the server to only check every ten minutes specify:

<config monitorInterval="10m" />

To disable file system polling and only reload when an MBean is notified specify:

<config updateTrigger="mbean" />

Log Messages

While the server is running it might output log messages that reference some config. When this happens an XPath-like structure is used. The element name is given with the value of the id attribute inside square brackets. If no id is specified in server config, an id is automatically generated. From the server XML config in the following example, the logs reference the dataStore element as dataStore[myDS] and the child dataSource would be identfied as dataStore[myDS]/dataSource[default-0] in logs.

<server>
    <dataStore id="myDS">
        <dataSource />
    </dataStore>
</server>