Spring boot is great framework to easily create applications with production-ready features such as metrics, health checks and externalized configuration.
You can create stand-alone applications with embedded servlet container or you can deploy application traditionally to application server. Unfortunately spring boot documentation lacks description, how to deploy multiple spring boot applications into one application server.
Generally it is better to run applications in separate instances of application servers. In this deployment model it is easier to manage resources and isolate application failures. But sometimes there are additional business requirements that several applications must run on one application server.
I found two common problems with deploying multiple spring boot applications to one application server:
- changing name of application.properties file
- conflicting jmx bean names
Changing name of application.properties file
Spring boot supports changing name of application.properties file by specifying spring.config.name environment property. This works great for one application, but when we deploy multiple applications into one server, the spring config name would change for all of our applications. So instead of specifying environment property we can supply this value in servlet initializer:
1
2
3
4
5
6
7
8
9
10
11
|
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
Map<String, Object> props = new HashMap<>();
props.put(“spring.config.name”, “my-app”);
application.properties(props);
return application.sources(MyApplication.class);
}
}
|
When we want to run application in stand-alone mode or from spring-boot maven plugin we can specify this value in environment property or add this to application main method:
1
2
3
4
5
6
7
8
9
|
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
System.setProperty(“spring.config.name”, “my-app”);
SpringApplication.run(MyApplication.class, args);
}
}
|
Similarly when running unit tests we can use environment property or add this to main test class constructor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
public class MyApplicationTests {
public MyApplicationTests() {
System.setProperty(“spring.config.name”, “my-app”);
}
@Test
public void contextLoads() {
}
}
|
Conflicting JMX bean names
Many libraries publish jmx beans. Jmx bean names must be unique in JVM. When we deploy two spring boot applications into one application server there can be some name clashes. Fortunately there are ways for changing published bean names. For example you can change spring boot actuator jmx domain by specifying endpoints.jmx.domain property.