WildFly Swarm for Microservices
The last Java microservice framework we’ll look at is a relative newcomer to the scene yet leverages tried-and-trusted Java EE functionality found in the JBoss WildFly application server. WildFly Swarm is a complete teardown of the WildFly application server into bitesized, reusable components called fractions that can be assembled and formed into a microservice application that leverages Java EE APIs. Assembling these fractions is as simple as including a dependency in your Java Maven (or Gradle) build file, and WildFly Swarm takes care of the rest.
Application servers and Java EE have been the workhorse of enterprise Java applications for more than 15 years. WildFly (formerly JBoss Application Server) emerged as an enterprise-capable, open source application server. Many enterprises heavily invested in the Java EE technology (whether open source or proprietary vendors) from how they hire software talent as well as overall training, tooling, and management. Java EE has always been very capable at helping developers build tiered applications by offering functionality like servlets/JSPs, transactions, component models, messaging, and persistence. Deployments of Java EE applications were packaged as EARs, which typically contained many WARs, JARs, and associated configuration. Once you had your Java archive file (EAR/WAR), you would need to find a server, verify it was configured the way you expect, and then install your archive. You could even take advantage of dynamic deployment and redeployment (although doing this in production is not recommended, it can be useful in development). This meant your archives could be fairly lean and only include the business code you needed. Unfortunately, this lead to bloated implementations of Java EE servers that had to account for any functionality that an application might need. It also led to over-optimization in terms of which dependencies to share (just put everything in the app server!) and which dependencies needed isolation because they would change at a different rate from other applications.
The application server provided a single point of surface area for managing, deploying, and configuring multiple applications within a single instance of the app server. Typically you’d cluster these for high availability by creating exact instances of the app server on different nodes. The problems start to arise when too many applications share a single deployment model, a single process, and a single JVM. The impedance arises when multiple teams who develop the applications running inside the app server have different types of applications, velocities of change, performance or SLA needs, and so on. Insofar as microservices architecture enables rapid change, innovation, and autonomy, Java EE application servers and managing a collection of applications as a single, all-in-one server don’t enable rapid change. Additionally, from the operations side of the house, it becomes very complex to accurately manage and monitor the services and applications running within a single application server. In theory a single JVM is easier to manage, since it’s just one thing, but the applications within the JVM are all independent deployments and should be treated as such. We can feel this pain when we try to treat the individual applications and services within a single process as “one thing,” which is why we have very expensive and complicated tooling to try and accomplish that introspection. One way teams get around some of these issues is by deploying a single application to an application server.
Even though the deployment and management of applications within a Java EE environment may not suit a microservices environment, the component models, APIs, and libraries that Java EE provides to application developers still provide a lot of value. We still want to be able to use persistence, transactions, security, dependency injection, etc., but we want an à la carte usage of those libraries where needed. So how do we leverage our knowledge of Java EE, the power it brings within the context of microservices? That’s where WildFly Swarm fits in.
WildFly Swarm evaluates your pom.xml (or Gradle file) and determines what Java EE dependencies your microservice actually uses (e.g., CDI, messaging, and servlet) and then builds an uber JAR (just like Spring Boot and Dropwizard) that includes the minimal Java EE APIs and implementations necessary to run your service. This process is known as “just enough application server,” which allows you to continue to use the Java EE APIs you know and love and to deploy them both in a microservices and traditional-application style. You can even just start using your existing WAR projects and WildFly Swarm can introspect them automatically and properly include the requisite Java EE APIs/fractions without having to explicitly specify them. This is a very powerful way to move your existing applications to a microservice-style deployment.