Turn your WildFly application in a Bootable JAR

WildFly Bootable JAR is a Maven plugin which allows you to turn your Enterprise applications in a runnable Jar file, which includes just the layers of WildFly you need to run your application. In this article we will learn how to build an Enterprise application with this technology. Also, in the latter part of it, we will learn how to use WildFly glow to automate the creation of a Bootable JAR.

How to create a Bootable WildFly JAR

The core technology behind WildFly Bootable JAR is Galleon. This framework allows to combine layers of the application servers in order to produce a WildFly distribution according to your application needs.

In order to create a Bootable WildFly JAR you need to include the wildfly-jar-maven-plugin plugin in your pom.xml. This plugin does the magic to transform your application into a bootable WildFly application server with the application running on the top of it:

<plugin>
  <groupId>org.wildfly.plugins</groupId>
  <artifactId>wildfly-jar-maven-plugin</artifactId>
  <version>${version.bootable.jar}</version>
</plugin> 

It is a good idea to specify the plugin version as a property:

<version.bootable.jar>10.0.0.Final</version.bootable.jar>

Then, to specify the WildFly version and the Galleon layers to include in your server structure, we will use the configuration element of the wildfly-jar-maven-plugin:

<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-server</layer>
      </layers>
      <plugin-options>
          <jboss-fork-embedded>true</jboss-fork-embedded>
      </plugin-options>
      <cloud/>
    </configuration>
    <executions>
      <execution>
        <goals>
          <goal>package</goal>
        </goals>
      </execution>
    </executions>
</plugin>

Some information about the configuration. First of all, the feature-pack-location specifies the WildFly version you will be using. Therefore, to provision WildFly 31:

<feature-pack-location>wildfly@maven(org.jboss.universe:community-universe)#31.0.0.Final</feature-pack-location>

If you don’t specify the version, the Maven plugin will pick up the latest version WildFly:

<feature-pack-location>wildfly@maven(org.jboss.universe:community-universe)</feature-pack-location>

Within the layers section you can specify which layers you want to include or exclude when building up the WildFly server. For example, to provision a server containing jaxrs support without the deployment scanner:

<layers>
    <layer>jaxrs</layer>
</layers>

<excluded-layers>
    <layer>deployment-scanner</layer>
</excluded-layers>

A concrete application example

Let’s transform a standard JAX-RS application ( from our RESTEasy tutorial ) into a Bootable JAR File.

Firstly, build the application as usual with:

mvn install

You will notice that the JAR file rest-demo-bootable.jar has been created. You can run it with:

java -jar target/rest-demo-bootable.jar

Alternatively, you can also run the application as follows:

mvn wildfly-jar:run

You should expect the following output, which shows our example application was added under the rest-demo context:

wildfly bootable jar tutorial

You can test any of the REST Service (which has been bound to the Root Web Context) as follows:

curl -s http://localhost:8080/rest/itemListJson | jq
[
  {
    "description": "computer",
    "price": 2500
  },
  {
    "description": "chair",
    "price": 100
  },
  {
    "description": "table",
    "price": 200
  }
]

The source code for this application is available here: https://github.com/fmarchioni/mastertheboss/tree/master/bootable-jar/basic

Creating an hollow jar

By setting the hollow-jar option to true in the pom.xml you will be able to generate an Hollow Jar of the application server. This means, you will create the Runtime environment to start WildFly, in case you want to provide the application at runtime through the management interface:

 <hollow-jar>true</hollow-jar>

You can boot the hollow-jar application server just the same way:

java -jar target/rest-demo-bootable.jar

You should expect that the application server starts up but no applications are deployed on the top of it:

10:17:07,781 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-5) WFLYUT0006: Undertow HTTP listener default listening on 127.0.0.1:8080
10:17:07,843 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server
10:17:07,846 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) started in 1202ms - Started 110 of 114 services (29 services are lazy, passive or on-demand)
10:17:07,847 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management

Making your application cloud-aware

To allow the deployment of your Bootable Jar application in a Cloud environment, such as Kubernetes or OpenShift, you need to include the cloud element in your configuration:

<cloud/>

This will configure your JGroups stack for a cloud environment. Would you like to deploy this application on OpenShift using Helm Charts? then check this article: WildFly on the Cloud with Helm

Checking the start up time and memory usage of the Bootable jar

By running the application as Bootable jar, shows a remarkable increase in server start up, which accounts for just 1.1 seconds:

WFLYSRV0025: WildFly Full 20.0.0.Final (WildFly Core 12.0.1.Final) started in 1185ms - Started 83 of 87 services (23 services are lazy, passive or on-demand)

Also, if you check the Resident Memory Size of the Hollow Jar application, it takes about 213 MB as you can see from the top output:

PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND 
17470 frances+  20   0   11.8g 213184  16984 S   0.3   0.7   1:15.11 java  

That’s less than the half of the standard WildFly server distribution with our application on top of it:

PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND 
16307 frances+  20   0 1936116 472296  20300 S   2.0   1.5   0:28.03 java  

Creating a Bootable JAR with WildFly Glow

Here is a recent update to this tutorial. You can now use a simpler approach to build a Bootable JAR without including manually all layers in your pom.xml. By running WildFly Glow, you can inspect your artifacts and generate automatically a Bootable JAR which includes exaclty what you need.

For example, to create a Bootable JAR from your artifact kitchensink, you can run as follow WildFly Glow’s CLI:

./wildfly-glow scan ./examples/kitchensink.war --provision=BOOTABLE_JAR

You can read more about WildFly Glow in this article: WildFly Glow: Next-Gen Evolution in Provisioning

Conclusion

WildFly bootable jar is a remarkable advancement to build a self-contained application using the technologies you are familiar with and the management options of WildFly application server. In the next tutorial we will learn how to create a Clustered Application using WildFly bootable JAR: Creating a clustered application with WildFly bootable JAR