How to execute CLI scripts in WildFly Bootable Jar

WildFly Bootable jar is a plugin that lets you run your WildFly applications into bootable microservice-like components. This tutorial covers how to execute CLI script during the packaging or at runtime, to customize your bootable JAR configuration.

There are two ways to run CLI management scripts on the top of your executable Bootable Jar:

  • Execute CLI scripts during the packaging of the bootable JAR
  • Execute CLI scripts on the top of a runnable JAR file

Before diving into the two operation modes, let’s create a sample JAX-RS application that can run as a Bootable JAR file:

package com.mastertheboss.jaxrs.service;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;

@Path("/")
public class SimpleRESTService {

	@GET
	@Path("property/{name}")
	public String helloProperty(@PathParam("name") final String name) {
		return "Hello " +System.getProperty(name);
	}
 
}

This REST Endpoint returns the value of a System Property. We will use the CLI scripts to inject two System Properties.

To activate the JAX-RS endpoint, an Activator is needed:

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

@ApplicationPath("/rest")
public class JaxRsActivator extends Application {
   /* class body intentionally left blank */
}

Done with the application code, let’s add the pom.xml:

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.mastertheboss.jaxrs</groupId>
  <artifactId>rest-demo</artifactId>
  <packaging>war</packaging>
  <version>1.0.0</version>
  <name>Demo REST Service</name>
  <url>http://www.mastertheboss.com</url>
  <properties>
    <version.bootable.jar>4.0.3.Final</version.bootable.jar>
    <version.wildfly>23.0.0.Final</version.wildfly>
    <plugin.fork.embedded>true</plugin.fork.embedded>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <failOnMissingWebXml>false</failOnMissingWebXml>
    <version.server.bom>${version.wildfly}</version.server.bom>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>jakarta.platform</groupId>
        <artifactId>jakarta.jakartaee-api</artifactId>
        <version>8.0.0</version>
        <scope>provided</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>jakarta.platform</groupId>
      <artifactId>jakarta.jakartaee-api</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jakarta.xml.bind</groupId>
      <artifactId>jakarta.xml.bind-api</artifactId>
      <version>2.3.3</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
      <plugin>
        <groupId>org.wildfly.plugins</groupId>
        <artifactId>wildfly-jar-maven-plugin</artifactId>
        <version>${version.bootable.jar}</version>
        <configuration>
          <feature-pack-location>wildfly@maven(org.jboss.universe:community-universe)#${version.server.bom}</feature-pack-location>
          <layers>
            <layer>jaxrs</layer>
            <layer>management</layer>
          </layers>
          <excluded-layers>
            <layer>deployment-scanner</layer>
          </excluded-layers>
            <cli-sessions>
                <cli-session>
                    <script-files>
                        <script>packagescript.cli</script>
                    </script-files>
                </cli-session>
            </cli-sessions>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>package</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

As you can see, the wildfly-jar-maven-plugin has been added as a Maven plugin. Within this file, we have added a cli-sessions element so that a CLI script will be run during the packaging.

Here is the packagescript.cli:

/system-property=name:add(value=john)

Let’s build our application:

$ mvn clean install

[INFO] Executing CLI, Server configuration
WARN: can't find jboss-cli.xml. Using default configuration values.
[INFO] CLI scripts execution done.
[INFO] Executing CLI, CLI Session, scripts=[packagescript.cli], resolve-expressions=true, properties-file=null
     . . . . .
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  14.391 s
[INFO] Finished at: 2021-05-24T08:51:43+02:00
[INFO] ------------------------------------------------------------------------

Within the build log, there is evidence of the CLI script execution which has been completed.

We will now add another CLI script named runtimescript.cli:

/system-property=surname:add(value=Smith)

Now let’s run the application passing as argument the “–cli-script” to allow the runtime execution of the runtimescript.cli:

java -jar target/rest-demo-bootable.jar --cli-script=runtimescript.cli

The application server will boot and the application (“rest-demo”) will be deployed in the ROOT context:

08:53:48,366 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0010: Deployed "rest-demo.war" (runtime-name : "ROOT.war")
08:53:48,382 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server
08:53:48,383 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 23.0.0.Final (WildFly Core 15.0.0.Final) started in 1611ms - Started 160 of 166 services (33 services are lazy, passive or on-demand)
08:53:48,384 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
08:53:48,384 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0054: Admin console is not enabled

Let’s test the first property:

$ curl http://localhost:8080/rest/property/name
Hello john

And then the other:

$ curl http://localhost:8080/rest/property/surname
Hello Smith

As you can see, both System Properties have been injected by the CLI scripts.

Please note that Runtime execution of CLI scripts, passing as argument the “–cli-script“,  is available for WildFly 23 or newer.

Using Properties in CLI scripts

It is worth mentioning, that the Bootable Jar plugin allows to store CLI properties in a separate file, just like the jboss-cli.sh tool does.

To do that, add a properties-file block in the cli-session element:

  <cli-sessions>
        <cli-session>
            <properties-file>
               cli.properties
            </properties-file>
            <script-files>
                <script>packagescript.cli</script>
            </script-files>
        </cli-session>
    </cli-sessions>

Then, in your CLI script, you can use properties:

/system-property=name:add(value=${name})

The value of ${name} is resolved in the file cli.properties:

name=john

Source code for this demo: https://github.com/fmarchioni/mastertheboss/tree/master/bootable-jar/scripts