by BehindJava

How to add another WAR files to the embedded tomcat

Home » springboot » How to add another WAR files to the embedded tomcat

In this tutorial we are going to learn about adding another WAR files to the embedded tomcat.

Spring Boot’s embedded tomcat is very handy, for both development and deploy.

But what if an another (3rd-party) WAR file (for example, GeoServer) should be added?

Perhaps the following is the normal procedure:

  • Install a normal Tomcat server.
  • Build the Spring Boot application as a WAR file, and add it to the webapps folder of the Tomcat.
  • Also add an another (3rd-party) WAR file to the webapps folder.

But it would be nice if the following configuration were possible.

  • Build the Spring boot application as a standalone Jar, which includes the embedded Tomcat.
  • Deploy the Spring boot application Jar.
  • Add an another (3rd-party) WAR file to a folder which the embedded Tomcat recognizes.
  • Serve both the Spring boot application contents and the another WAR’s contents using the embedded Tomcat.

How can it be done?

UPDATE

When the spring boot application is made of fat jar(=executable jar), the code in the answer is not enough. The revised one is as follows:

@Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
    return new TomcatEmbeddedServletContainerFactory() {

        @Override
        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                Tomcat tomcat) {
            try {
                Context context = tomcat.addWebapp("/foo", "/path/to/foo.war");
                WebappLoader loader =
                    new WebappLoader(Thread.currentThread().getContextClassLoader());
                context.setLoader(loader);
            } catch (ServletException ex) {
                throw new IllegalStateException("Failed to add webapp", ex);
            }
            return super.getTomcatEmbeddedServletContainer(tomcat);
        }

    };
}

Since the jar files in a fat jar cannot be loaded by the system classloader, an explicit parent classloader must be specified. Otherwise, the additional WAR cannot load the library jars in the fat jar of the spring boot application that added the WAR.