Coming Up for Air

Getting Started with Eclipse MicroProfile, Part 3: Thorntail

In the last installment, we talked about Payara Micro. In this, we’re going to look at Thorntail. Thorntail, née Wildfly Swarm, is based on Wildfly from Red Hat and is said to be "just enough app-server". Much like Payara Micro, Thorntail exposes a battle-tested application server platform, stripped down for microservices usage. Let’s a take a look at what it takes to deploy our application on Thorntail.

Before getting, it’s worth pointing to the Thorntail documentation, which seems to be very complete and thorough. If you’d like to peruse that now, feel free. We’ll be here when you’re done.

To get started, we need to create a new project, and add a few odds and ends to our build. Somewhat surprisingly, the required changes seem to be much smaller and simpler than those required by Payara Micro:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mp-demo-master</artifactId>
        <groupId>com.steeplesoft.microprofile</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>thorntail</artifactId>
    <packaging>war</packaging>

    <properties>
        <version.thorntail>2.2.0.Final</version.thorntail>
     </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.shrinkwrap.resolver</groupId>
                <artifactId>shrinkwrap-resolver-bom</artifactId>
                <version>3.1.3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>io.thorntail</groupId>
                <artifactId>bom</artifactId>
                <version>${version.thorntail}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>io.thorntail</groupId>
            <artifactId>microprofile</artifactId>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>io.thorntail</groupId>
            <artifactId>arquillian</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>io.thorntail</groupId>
                <artifactId>thorntail-maven-plugin</artifactId>
                <version>${version.thorntail}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

I decided to include the entire POM, as it’s really rather small. We import the BOM in dependencyManagement, add one dependency to pull in Thorntail, one for our application, and one (ONE!) for the Arquillian tests. Likewise, we have a single build plugin.

Note

I had to include an updated version for ShrinkWrap, as the version included transitively from io.thorntail:arquillian was old and was causing test failures due to odd dependency look-ups against Central.

Like Payara Micro, we build this as a war file, so we have the same empty src/main/webapp/WEB-INF/beans.xml file to trigger CDI processing. That is literally all we have to do. I even copied and pasted the tests, which run unchanged (yes, I could probably define those in another module and import them, but it’s not that important to me right now. :)

When I run mvn install, I see the following in the target directory:

#ll -h target/
 total 104M
 drwxr-xr-x 1 jdlee jdlee    0 Oct 15 13:31 generated-test-sources
 drwxr-xr-x 1 jdlee jdlee    0 Oct 15 13:32 maven-archiver
 drwxr-xr-x 1 jdlee jdlee    0 Oct 15 13:31 maven-status
 drwxr-xr-x 1 jdlee jdlee    0 Oct 15 13:32 surefire-reports
 drwxr-xr-x 1 jdlee jdlee    0 Oct 15 13:31 test-classes
 drwxr-xr-x 1 jdlee jdlee    0 Oct 15 13:32 thorntail-1.0-SNAPSHOT
 -rw-r--r-- 1 jdlee jdlee 3.3M Oct 15 13:32 thorntail-1.0-SNAPSHOT.war
 -rw-r--r-- 1 jdlee jdlee  27M Oct 15 13:32 thorntail-1.0-SNAPSHOT.war.original
 -rw-r--r-- 1 jdlee jdlee 1.9K Oct 15 13:32 thorntail-1.0-SNAPSHOT-classes.jar
 -rw-r--r-- 1 jdlee jdlee  74M Oct 15 13:32 thorntail-1.0-SNAPSHOT-thorntail.jar

And I can start my application using the -thorntail.jar uberjar:

# java -jar target/thorntail-1.0-SNAPSHOT-thorntail.jar
...
2018-10-15 13:37:15,328 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 6) WFLYUT0021: Registered web context: '/' for server 'default-server'
2018-10-15 13:37:15,364 INFO  [org.jboss.as.server] (main) WFLYSRV0010: Deployed "thorntail-1.0-SNAPSHOT.war" (runtime-name : "thorntail-1.0-SNAPSHOT.war")
2018-10-15 13:37:15,371 INFO  [org.wildfly.swarm] (main) THORN99999: Thorntail is Ready

Manual testing works just the same as it did with Payara Micro:

# curl http://localhost:8080
Hello, world
# curl http://localhost:8080/?name=Thorntail
Hello, Thorntail

With that, we’ve finished another simple MicroProfile deployment with zero changes to our application, and no container-specific code, but we’ll circle back to that idea when we wrap up the series.

You can find the source for the whole project here, and for this part here.

Up next, OpenLiberty!

Quotes

Sample quote

Quote source