Building Microservices from WildFly applications

This tutorial is about building Microservices applications for WildFly developers. The main objective of this tutorial is to discuss the key challenges and solutions around building Microservices using Enterprise API in the Enterprise application environment.

Microservice architecture is one of the most widely discussed and adopted architecture pattern in the modern IT Industry. With the rise of cloud-native architecture, software applications are no longer built as monolithic applications, rather as a collection of services or serverless functions, leveraging technologies such as Docker and Kubernetes. Let’s see how we can turn our applications running on WildFly into a service.

Option 1: Trim your WildFly Server using Galleon Layers

WildFly is an application server therefore it can be used to deploy multiple applications in a monolithic environment. Its subsystems are designed for this purpose, so they can provide you a full Java Enterprise stack for your applications. In addition, you can leverage some of the Eclipse Microprofile features, to provide essential features for Microservices like Opentracing, Health checking, Metrics and Configuration:

<extension module="org.wildfly.extension.microprofile.config-smallrye"/>
<extension module="org.wildfly.extension.microprofile.health-smallrye"/>
<extension module="org.wildfly.extension.microprofile.metrics-smallrye"/>
<extension module="org.wildfly.extension.microprofile.opentracing-smallrye"/>

Starting with WildFly 16, we can use Galleon layers to control the features included in a WildFly server. A Galleon layer identifies one or more server features that can be installed on its own or in combination with other layers. For example, if you want to deliver a microservice-like application which makes use of only the jaxrs and cdi server features, then you can choose to install just these layers with Galleon. The configuration in standalone.xml would then contain only the required subsystems and their dependencies.

In this tutorial you can check more about building a WildFly server with Galleon: Provisioning WildFly with Galleon

Advantage No changes are required at all in your code, nor in configuration. You can also retain Management features of Domain mode
 Challenge Still running a monolithic architecture. The amount of resources used for this service will be typically higher than a standalone microservice.

Option 2: Convert your application to a Bootable WilFly jar

WildFly bootable jars are a new way to package applications which specifically target microservice deployments, allowing us to boot our Enteprirse/Microprofile application just from one jar file.

Thanks to Galleon technology it is possible to combine layers of the application servers in order to produce a WildFly distribution according to your application needs. On the top of that a Maven plugin has been developer to allow combining your application and the server in a single bootable JAR.

You can read more about Runnable WildFly Jars in this tutorial: Turn your WildFly applications in bootable JARs

Advantage No changes are required at all in your code. You just have to add the Maven plugin in your pom.xml
Advantage Tha amount of memory used by Hollow Jar files produced is significantly lower than the standard WildFly server which makes it a good git for microservice development.
 Challenge The project is still in Beta stage.

Option 3: Turn your application into a Quarkus application

wildfly microservices tutorial wildfly microservices tutorial

Quarkus is a Kubernetes Native Java stack tailored for GraalVM & OpenJDK HotSpot, crafted from the best of breed Java libraries and standards.

Besides it, Quarkus gives you a massive improvement in speed and memory footprint as it can produce native executables to be deployed on the cloud. It includes as well a native hot swapping feature that increases your productivity by several magnitudes. Here is an Hello World Quarkus tutorial: Getting started with QuarkusIO

In terms of migration, the first step to migrate a WildFly application into Quarkus is adding the parent bom file:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-bom</artifactId>
    <version>${io.quarkus.version}</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

Then you will need adding the single dependencies, in replacement for WildFly dependencies:

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-resteasy</artifactId>
</dependency>

In terms of configuration, Quarkus does not have an XML configuration file like WildFly nor it uses YAML file as Thorntail. Its configuration is based on the Microprofile Config API, therefore an application.properties file is used instead:

quarkus.log.console.enable=true
quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c] %s%e%n
quarkus.log.console.level=TRACE

In terms of code, Quarkus fully supports the Microprofile stack, making it a perfect fit for Microservices, plus a subset of Java Enterprise API (focusing mostly on CDI, JAXRS, JSONB, JSONP). In addition, you can plugin in some key extensions like Vert.x, Kafka, Kogito, Keycloak and many more. (You can check it with the ‘mvn quarkus:list-extensions’ command)

AdvantageCapability to create native executables
AdvantageOut of the box packaging of the applications for cloud deployments.
AdvantageNative live coding.
AdvantagePerfect to design Stream-based and Reactive applications
AdvantageAlready a large set of extensions available, including core Enterprise API
ChallengeSome legacy API (EJB, JAX-WS, JSF, Corba) are not included in QuarkusIO. Some reengineering might be required.
ChallengeYou have to replace Domain Mode Management features with Openshift/Kubernates management

Option 4: Turn your application into a MicroProfile compatible solution with Thorntail (deprecated)

wildfly microservices tutorial wildfly microservices tutorial

IMPORTANT: The Thorntail project (formerly known as WildFly Swarm) has reached End Of Life. The last Thorntail release is the 2.7.0. You are recommended to evaluate a migration plan for your applications. Check this tutorial to learn more: How to migrate Thorntail applications

This solution requires some adjusting in your pom.xml file in order to replace the Java EE dependencies with Thorntail dependencies. A Thorntail application is typically configured as follows: A BOM file which contains the version for all fractions:

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

Then declare the fractions you need:

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

Then, generate the uberjar and run it:

$ mvn package
$ java -jar <myapp>-thorntail.jar

In addition, you will have to turn the configuration of WildFly subsystems into YAML configuration snippets, as in this example, which configures a Datasource:

swarm:
  datasources:
    jdbc-drivers:
      org.postgresql:
        driver-class-name: org.postgresql.Driver
        xa-datasource-class-name: org.postgresql.xa.PGXADataSource
        driver-module-name: org.postgresql
    data-sources:
      ExampleDS:
        driver-name: org.postgresql
        connection-url: jdbc:postgresql://localhost:5432/postgres"
        user-name: postgres
password: postgres

One advantage of moving your application to Thorntail is the large list of fractions which greatly enhance the standard Java Enterprise API. Besides all Java EE, you can include fractions for Monitoring, the Netflix API, the full Eclipse MicroProfile stack, NoSQL data and much more!

On the other hand, you will not be able to retain the management features of WildFly in Domain mode when switching to Thorntail. One best practice would be to deploy the application on a Kubernates environment, like Openshift, and use Openshift HA and network capabilities as a replacement for  WildFly Domain configuration.

AdvantageNo code changes are normally required to port your existing Enterprise applications on Thorntail.
AdvantageComplements the Enterprise API with a large set of popular API that are a perfect fit for Microservices applications
ChallengeThe Thontail project has reached EoL. Consider migrating to Quarkus or WildFly runnable Jars
ChallengeRequires to transform your configuration from the standalone.xml file to YAML fractions
ChallengeYou cannot run Thorntail in Domain mode as WildFly server

That was all about! Enjoy your Microservices applications with WildFly, Thorntail or Quarkus!