Creating a clustered application with WildFly bootable JAR

In this article we will learn how to create a simple clustered HTTP application using WildFly bootable jar option

First of all, we recommend having a look at the first tutorial which gives some basic exposure to WildFly bootable jars: Turn your WildFly applications in bootable JARs

That being said, in order to provision a bootable WildFly instance with HTTP Clustering we need the web-server and web-clustering layer in our wildfly-jar-maven-plugin configuration:

<build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-jar-maven-plugin</artifactId>
                <version>2.0.0.Final</version>
                <configuration>
                    <feature-pack-location>wildfly@maven(org.jboss.universe:community-universe)#${version.wildfly}</feature-pack-location>
                    <layers>
                        <layer>web-server</layer>
                        <layer>web-clustering</layer>
                    </layers>
                    <excluded-layers>
                        <layer>deployment-scanner</layer>
                    </excluded-layers>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Please notice that the web-clustering layer does not include mod_cluster but uses Infinispan and jgroups to make up the cluster. Therefore, putting a mod_cluster front-end in the picture won’t enable discover of servers.

That being said, we will create a minimal Servlet application which simply stores a counter in the session, so that we can check if the HTTP Session is working:

@WebServlet(urlPatterns = {"/"})
public class DemoServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException  {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        Integer count = 1;
        HttpSession session = request.getSession(false);
        if (session == null)
        {

            session = request.getSession();
            out.println("Session created: "+session.getId());
            session.setAttribute( "counter", count );
        }

        else
        {
            out.println("Welcome Back!");
            count = (Integer) session.getAttribute( "counter" );
            ++count;
            session.setAttribute( "counter", count );
        }
            out.println("<br>Counter " + count);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }


    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

}

Also, enable in web.xml the application to be distributable:

<web-app  xmlns="http://java.sun.com/xml/ns/j2ee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                              http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
          version="2.4">
    <distributable/>
</web-app>

You can build you application with:

mvn package

Now open two shells and start two instances of the application server:

$ java -jar target/cluster-demo-bootable.jar -Djboss.node.name=node1 
$ java -jar target/cluster-demo-bootable.jar -Djboss.node.name=node2 -Djboss.socket.binding.port-offset=100

You will see from the Console logs that the Cluster has been created:

09:57:39,478 INFO  [org.infinispan.CLUSTER] (thread-6,ejb,node1) ISPN000094: Received new cluster view for channel ejb: [node1|1] (2) [node1, node2]
09:57:39,492 INFO  [org.infinispan.CLUSTER] (thread-6,ejb,node1) ISPN100000: Node node2 joined the cluster
09:57:40,160 INFO  [org.infinispan.CLUSTER] (remote-thread--p3-t1) [Context=default-server] ISPN100002: Starting rebalance with members [node1, node2], phase READ_OLD_WRITE_ALL, topology id 2

Now you can try reaching the Servlet (deployed on the Root context) at http://localhost:8080

wildfly bootable jar in a cluster

Now you can try crashing this server (Control+C for example). You will see from the other server’s logs that:

09:57:55,687 INFO  [org.infinispan.CLUSTER] (thread-7,ejb,node2) ISPN100001: Node node1 left the cluster

Now, reach the second server and check that the counter is still increasing:

wildfly bootable jar in a cluster

You can check the source code for this example at: https://github.com/fmarchioni/mastertheboss/tree/master/bootable-jar/cluster


Recommended Articles

Configure Jakarta Persistence API with WildFly Bootable JAR

Learn how to configure Datasource connections for Jakarta Persistence API in WildFly Bootable JAR.

Execute CLI Scripts in WildFly Bootable Jar: A Step-by-Step Guide

Learn how to customize your WildFly Bootable JAR configuration by executing CLI scripts during packaging or at runtime. Follow our expert guide to get started with bootable microservice-like components.

WildFly Bootable Jar with Embedded-Artemis MQ Server - A Comprehensive Guide

Learn how to embed Artemis MQ Server in a WildFly Bootable Jar for Jakarta EE applications. #WildFly27 #ArtemisMQ #BootableJar #JavaEE

Learn How to Use OpenTelemetry API with WildFly Bootable Jar Technology

Master using OpenTelemetry API for observability in your WildFly bootable jar service. Learn from expert tutorials.