Java EE Microservices with

swarm logo 200px

Peter Palaga, Red Hat

About me

Peter Palaga


  • Java EE

  • Microservices architectures

  • WildFly Swarm

    • Uberjar, Fractions

    • Demo: "Swarmify" a traditional EE Application

    • Configuration

  • Advanced topics

    • Secure access (Keycloak), Service registration and discovery, Load Balancing & Circuit Breaking, and API documentation (Swagger).

Java EE

Please raise your hand if you ever wrote or maintained

  • Java Servlet

  • EJB

  • JAX-RS Endpoint

  • Persistence with Hibernate

Java EE

(application developer’s perspective)

  • A set of API specifications

    • Servlet, EJB, JAX-RS, JPA, JTA, CDI, JMS, …​

  • Packaged together as an Application Server

  • Several implementations

    • WildFly/JBoss EAP, WebSphere, WebLogic, …​

  • History since 1999, latest EE 7 from 2013, MicroProfile


Based on recent inovations

  • CI/CD

  • Linux containers

  • DevOps culture

Divide the functionality into reasonably small units, a.k.a. Microservices

  • Communication through REST or other language independent protocols

  • Isolation: Languages, Runtimes, Datastores, Release cycles, (DevOps) teams

Why Java EE still matters?

  • Robust, mature

  • Well understood (performance, scalability)

  • Standards compliant

  • Integrations

  • Investments (workforce, code in production)

How can Java EE fit in?

Java EE App Servers have to carry all APIs to get certified

  • Large in terms of disk space

  • (Some) slow to boot

  • (Some) require a lot of memory

…​ but my app does not need all of the APIs!

Welcome WildFly Swarm!

What is WildFly Swarm?

  • Open source project sponsored by Red Hat

  • A decomposition on WildFly Java EE Application Server

  • Take only the APIs you need (Just enough AppServer)

  • Package into a single runnable JAR (Uberjar) together with your application

WildFly Swarm core concepts


A self-contained JAR

  • Your application

  • The parts of WildFly necessary to run it

  • An internal Maven repository of dependencies

  • A piece of bootstrap code

Hollow Uberjar

  • Like Uberjar but contains no application code.

    java -jar myruntime-hollow-swarm.jar my-app.war
  • Useful with layered Linux containers:

    • Layer n: Hollow Uberjar runtime

    • Layer n+1: the application

  • Reduces the provisioning overhead and boot time

  • This is how WildFly Swarm implements MicroProfile


  • Well-defined collections of capabilities

  • Expressed as Maven GAVs

  • Autodetected at build time or explicitly declared

  • Configurable, with reasonable defaults

  • May map to

    • WildFly subsystems (read: Java EE APIs)

    • Any external code (Jolokia, Netflix Ribbon, Swagger, …​)

  • List of Fractions

How to swarmify a WAR (1/2)

Let’s have a traditional Java EE application


How to swarmify a WAR (2/2)

<plugin>  <!-- Add the wildfly-swarm-plugin -->
mvn package                                # build
ls target                                  # check what has
... javaee7-simple-sample-swarm.jar ...    #   been built
java -jar javaee7-simple-sample-swarm.jar  # run the uberjar

Where are the Fractions?

Autodetected by wildfly-swarm-plugin or declared explicitly:

<dependency> <!-- under dependencyManagement -->
<dependencies> <!-- Fraction GAVs -->

Start from scratch

WildFly Swarm Generator

WildFly vs. WildFly Swarm

Disk size

WildFlyWildFly Swarm (Uberjar)

148 MB

177 MB unzipped

36 MB plain Servlet

47 MB above + JAX-RS

86 MB above + CDI

100 MB above + JPA/Hibernate


WildFlyWildFly Swarm

Copy and unzip WildFly


Configure (datasources, …​)

Deploy the app

Copy the uberjar to the server

Run the uberjar

Missing parts

WildFly Swarm:

  • Will not run with a security manager

  • No EAR deployments

  • No clustering

    • Session replication, domain management, distributed caches, message broker

Areas open for contributions from the community


Java API

public static void main(String[] args) throws Exception {
  new Swarm().fraction(
    new DatasourcesFraction()
      .jdbcDriver("h2", (d) -> {
      .dataSource("ExampleDS", (ds) -> {
        ds.userName("sa"); ds.password("sa");


logger:               # project-defaults.yml file
  level: DEBUG
    offset: 10
project:              # To specify the "development" stage,
  stage: development  # run with
logger:               #   java -jar my-swarm.jar -S development
  level: DEBUG
    offset: 50
  stage: production
  level: INFO


  • Useful when migrating from a traditional WildFly deployment

  • Either

    java -jar my-swarm.jar -c my-standalone.xml
  • Or package standalone.xml in your uberjar by placing it to src/main/resources

  • Ensure that you have all subsystem fractions that you configure

Command line arguments and system properties

  • -b or -Dswarm.bind.address= to bind to a specific network interface

  • -Dswarm.port.offset=42 to shift ports - e.g. 8080 → 8122

  • -Dswarm.context.path=/my-app - note that the default is /

... and many others

Advanced topics

Secure access with Keycloak

What is Keycloak

  • JBoss community project

  • Single sign-on (SSO) server and identity broker

How to secure with Keycloak

<dependency> <!-- the keycloak client fraction in pom.xml -->
# project-defaults.yml
     auth-method: KEYCLOAK
     - url-pattern: /secured
       methods: [GET]
       roles: [admin]
/* WEB-INF/keycloak.json */
"realm": "wildfly-swarm-keycloak-example",
"bearer-only": true,
"auth-server-url": "http://localhost:8180/auth",
"ssl-required": "external",
"resource": "wildfly-swarm-keycloak-example"

Service registration

Service Registry
<!-- pom.xml -->
/* Inside main() method */
JAXRSArchive deployment = ...
/* register */
java -Dswarm.consul.url= -jar *-swarm.jar

Service discovery

  • Either directly through ConsulClient.getAgentServices()

  • Or via Netflix Ribbon integration

Netflix Ribbon

A REST inter-process communication library

  • Client-side load-balancing to other services

    • Several implementations: round Robin, response time weighted, random, …​

  • Integration with Service Registries

    • Services referenced by name rather than host

  • Built-in failure resiliency via Hystrix

Netflix Ribbon Fraction

<!-- pom.xml -->

Netflix Ribbon service client

                                         //    discovery by
@ResourceGroup( name="my-time-service" ) // <- service name
public interface TimeService {           //    lookup done
                                         //    by Consul fraction
            method = Http.HttpMethod.GET,
            uri = "/"
            fallbackHandler = TimeFallbackHandler.class
    RibbonRequest<ByteBuf> currentTime();

                           // Ribbon can provide an implementation
                           // of the TimeService
    TimeService INSTANCE = Ribbon.from(TimeService.class);

Swagger API Documentation

<!-- pom.xml -->
  <groupId>org.wildfly.swarm</groupId> <!-- typically      -->
  <artifactId>swagger</artifactId>     <!-- in combination -->
</dependency>                          <!-- with jaxrs     -->
/* Inside main() method */
SwaggerArchive archive =
    ShrinkWrap.create(SwaggerArchive.class, "swagger-app.war");
/* Tell swagger where our resources are */

Get the API Documentation

curl http://localhost:8080/swagger.json
{   "swagger":"2.0",
    "paths": {
        "/time/now": {
            "get": {
                "summary":"Get the current time",
                "description":"Returns the time as a string",
                "responses": {

WildFly Swarm Recap

  • Just enough Application Server

  • Uberjar or Hollow uberjar

  • Fractions to require and configure capabilites

  • WildFly Swarm Plugins for Maven and Gradle

Keep in touch