Server vs servlet containers

I have been working with JEE for a long time now, and with shift (or comeback, some might say) to micro service approach, it seemed that JEE and it's big full spec. implementing servers will not fit well into this concept.
For a long time there was a division between servlet containers and full blown JEE servers, or even servlet containers with spring vs JEE servers, and you would be stuck between minimal servlet containers and full blown application server. One would be small, the other full JEE spec, but heavy on the megabytes.
Well that's about to change.

Some time ago, I saw a post about the work done by group of people gathered around Wilfly server - they named the project Wildfly Swarm .

So what it does?

Using the Wildfly Swarm you can pick only the parts of JEE spec your application is using, and package it together with you application, creating small(ish) runnable jar. Dependencies can be resolved from local maven repos, or packaged into the jar with the application, depending on the needs.

Lets see an example

I was playing around with JEE7 on Wildfly building a simple example with websockets. Application itself is fairly simple, and stacked with JEE7 features for showcase, packaged as a war with no external dependencies - very small in size ~32K.

The code is on the git hub: https://github.com/dekstroza/JEE7/tree/master/websockets-example

What does it do? Offers rest api over which you can send a java log line, and it will distribute it to all connected clients. I also included couple of different websocket session management implementations and arquillian test case which measures time taken to deliver one message to 1000 connected websocket clients. Nothing special.

Traditionally, one would start Wildfly Server and deploy the application - which does not fit perfectly with the concept of docker containers. It would be much better if we could have just single jar to run inside container. Now, the problem with this is that Wildfly itself is heavy on size, alot of megabytes, and resulting jar would be huge.

This is where Wildfly Swarm comes into picture. Once included into maven build (yes you can use gradle if you have good reasons to use it here instead of maven), you can select which parts of JEE7 our application will be using, by listing appropriate Wildfly Swarm dependencies, and swarm will produce rather small jar - which is runnable.

In maven module which packs war, I need to include:

        <profile>
            <id>swarm</id>
            <activation>
                <activeByDefault>false</activeByDefault>
                <property>
                    <name>swarm</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <version>2.5.1</version>
                        <configuration>
                            <source>${java.source.version}</source>
                            <target>${java.target.version}</target>
                        </configuration>
                    </plugin>
                    <plugin>
                        <artifactId>maven-war-plugin</artifactId>
                        <version>2.2</version>
                        <configuration>
                            <warName>${project.artifactId}</warName>
                            <failOnMissingWebXml>false</failOnMissingWebXml>
                            <attachClasses>true</attachClasses>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.wildfly.swarm</groupId>
                        <artifactId>wildfly-swarm-plugin</artifactId>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <bundleDependencies>true</bundleDependencies>
                            <properties>
                                <swarm.context.path>${project.artifactId}</swarm.context.path>
                            </properties>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
            <dependencies>
                <dependency>
                    <groupId>org.wildfly.swarm</groupId>
                    <artifactId>jaxrs</artifactId>
                    <version>${wildfly.swarm.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.wildfly.swarm</groupId>
                    <artifactId>weld</artifactId>
                    <version>${wildfly.swarm.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.wildfly.swarm</groupId>
                    <artifactId>ejb</artifactId>
                    <version>${wildfly.swarm.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.wildfly.swarm</groupId>
                    <artifactId>undertow-modules</artifactId>
                    <version>${wildfly.swarm.version}</version>
                </dependency>
            </dependencies>
        </profile>

When this maven profile is activated, Wildfly Swarm will produce a jar in the target directory, and in this instance it will also bundle all dependencies, resulting in runnable jar 90Mb big. It can be simply ran with java -jar our_fancy_jar.jar and is perfect for a docker container, which we can produce as well using swarm and mvn docker plugin. If we choose not to bundle the dependencies, they would be resolved from maven repository, and the size of our jar would be roughly the same as the original application war - around 32K.

Keeping in mind this is just early stage project (current version at the moment being 1.0.8.Alpha, result if fantastic. Then, hooking the jar into container and testing container with the arquillian, and we have a nice testing setup ready for shipment into production too. You can find more details at http://wildfly-swarm.io

Sad thing though, it won't be available for production soon, as it relies on JEE7 and Wildfly 10 codebase. Comercial version of Wildfly 10, will most likely be Red Hat EAP7, so until then it's opensource hacking if you want to use/abused it.

Happy hacking,
Dejan