An example project showing the problems deploying Spring Boot applications to Wildfly in an EAR deployment using skinny WARs.
This project consist of several deployment scenarios:
A single EAR containing two Spring Boot Web Applications, web1
and web2
.
The EAR contains all (with one exception) the dependencies that both web1
and web2
require.
This avoids the duplicated dependencies. The wars are packaged as skinny WARs.
A EAR containing all dependencies, platform
.
A EAR, skinny-ear
containing two Spring Boot Web Applications, web1
and web2
.
Both the EAR and the WAR are skinny and do not include any dependencies provided by platform
.
A standalone WAR, skinny-war
, providing the context /skinny-web
- Wildfly does not find
SpringServletContainerInitializer
if it is in the EARlib
directory. This is discussed on https://issues.jboss.org/browse/WFLY-4205 and https://jira.spring.io/browse/SPR-12555. A fix should be in 9.0.0.Beta1 upwards, but it did not work for me. So I had to create theservlet-container-initializer-meta-inf
module and force it to be included in eachWEB-INF/lib
directory. - When
SpringServletContainerInitializer
is called it does not find Spring BootWebApplicationInitializer
classes inWEB-INF/classes
. When it interrogates the class loader, it only finds classes from the EARlib
folder. However, the WAR classes are on the class path and are found by Spring once it starts up. As a temporary work-around, I created a common Spring Boot application class and included it as a common JAR.
Since the Servlet 3.0 spec make externalizing dependencies out of the war troublesome we will instead use a method known to allow Spring Boot 1.x run within a Servlet 3.0 container.
Using a fork of dyser/spring-boot-legacy at ddcruver/spring-boot-legacy that has been updated to Spring Boot 2.0.2 we show that you can use Spring Boot 2.0.2 in an EAR with Skinny WARs in WildFly.
UPDATES: A pull request was made to update dyser/spring-boot-legacy to support Spring Boot 2.0. This pull request was accepted but an additional pull request was made to address more issues discovered in testing. See dsyer/spring-boot-legacy#25 and dsyer/spring-boot-legacy#26.
Tested Versions:
- WildFly 8.2.1.Final
- WildFly 9.0.2.Final
- WildFly 10.1.0.Final
- WildFly 11.0.0.Final
- WildFly 12.0.0.Final
Spring loads a completely separate context for each WAR. I would like it to share a root context to speed up loading and allow for shared components. There is an unanswered question on Stack Overflow http://stackoverflow.com/questions/31667392/spring-boot-ear-packaging and I have not yet found a solution.
- Download WildFly 8.2.1.Final+
- Build the project using
mvn clean package
- Deploy the spring-boot-ear-2.0.1.ear file to WildFly.
You should be able to hit http://localhost:8080/web1 and http://localhost:8080/web2
Username: user Password: Generated by default in Spring Boot 2.0 for each application which can be found in the logs.
14:09:11,335 INFO [org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration] (ServerService Thread Pool -- 79)
Using generated security password: 28f03f81-83fa-482f-9121-23950b634ead