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