Spring Boot with external Tomcat

Posted by thestars on Thu, 09 Jan 2020 07:48:14 +0100

In this article, I'll run the Spring Boot application on an external Tomcat.For me, this is a real situation and I have to solve this problem, so I also consulted a good teacher and got a lot of help.I hope you can provide some useful information when you encounter similar problems.

Let's look at some common problems you might encounter when starting a project from scratch.


Spring Boot Start Method

One of the main advantages of using Spring Boot is that you can easily set up a Web application using the built-in embedded Tomcat.By default, the AutoConfigurator uses Tomcat to set up your project.Just click the Run button and your Web server will start your application.In the application.yaml or properties file, you can easily configure this Tomcat server as follows:

1 server:
2    port: 9091 //set the port number of our running application
3    servlet:
4       context-path: /springapplication /set the context path of our application


To run our application, we only need one main method:

1 @SpringBootApplication
2 public class App 
3 {
4     public static void main( String[] args )
5     {
6     SpringApplication.run(App.class, args);
7     }
8 }





External Tomcat issues

You can expect the application to run on an external Tomcat server.Usually, it happens because of the operational infrastructure.At this point, some problems occurred.Your Spring Boot application will not start just by deploying it to a network server.There are several reasons for this:

  • By default, Spring Boot creates a.jar file as output.Tomcat needs a.war file.
  • In a Tomcat environment, you don't want to use an embedded server.
  • The Tomcat server will not use your primary method.Therefore, you need to start your application with a normal Spring application.

Spring Boot is a cutting-edge technology that primarily supports running in a containerized environment.What if you want to operate the application in a standard way?

First, you can go back to the native Spring you don't normally want.Second, you can make some modifications to prepare your application to run on an older Tomcat server.So I'll tell you how.





Running Spring Boot with external Tomcat

First, you need to make some modifications in pom.xml:

Set up war packaging for artifact s:

1 <packaging>war</packaging>

Set Tomcat server dependencies to provide:

1        <dependency>
2             <groupId>org.springframework.boot</groupId>
3             <artifactId>spring-boot-starter-tomcat</artifactId>
4             <scope>provided</scope>
5         </dependency>


If some of your Spring Boot libraries contain it by default, exclude it:

 1 <dependency>
 2 <groupId>org.springframework.boot</groupId>
 3 <artifactId>spring-boot-starter-web</artifactId>
 4             <exclusions>
 5                 <exclusion>
 6                     <groupId>org.springframework.boot</groupId>
 7                     <artifactId>spring-boot-starter-tomcat</artifactId>
 8                 </exclusion>
 9             </exclusions>
10 </dependency>

Finally, here's the trick: modify the application's default classes:

1 @SpringBootApplication
2 public class App extends SpringBootServletInitializer
3 {
4     public static void main( String[] args )
5     {
6     SpringApplication.run(App.class, args);
7     }
8 }


The SpringBootServerInitializer class does the following (obtained from the original class header):

1  * An opinionated {@link WebApplicationInitializer} to run a {@link SpringApplication} from a traditional WAR deployment. Binds {@link Servlet}, {@link Filter} and {@link ServletContextInitializer} beans from the application context to the server.
2  * To configure the application either override the {@link #configure(SpringApplicationBuilder)} method (calling {@link SpringApplicationBuilder#sources(Class...)}) or make the initializer itself a {@code @Configuration}. If you are using {@link SpringBootServletInitializer} in combination with other {@link WebApplicationInitializer WebApplicationInitializers} you might also want to add an {@code @Ordered} annotation to configure a specific startup order.
3  * Note that a WebApplicationInitializer is only needed if you are building a war file and deploying it. If you prefer to run an embedded web server then you won't need this at all.


With these modifications, you will be able to run your application from a traditional war deployment.





External configuration of Spring Boot App on Tomcat

Profiles can usually be read from external sources that IT departments can easily handle.

To do this, you need to override the configure method in the above class in the main class.

In the following example, I bring a real-time example.Here, I need to read the configuration path from the environment variable.They set it in Tomcat's server setenv.sh file.

 1 @Override
 2 protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
 3 String configLocation = System.getProperty("global.appconf.dir"); //get the default config directory location
 4     String configPath = configLocation + File.separator + "springApplication"  + File.separator + "application.yml"; //set the configpath of this application instance exclusively
 5     log.info("Configpath: " + configPath);
 6     log.info("Starting to run Spring boot app...");
 7     if(configLocation != null && !configLocation.isEmpty()) {
 8     Properties props = new Properties();
 9     props.setProperty("spring.config.location", configPath); //set the config file to use    
10     application.application().setDefaultProperties(props);
11     }else{
12     log.info("No global.appconf.dir property found, starting with default on classpath");
13     }
14 return application.sources(SpringApplication.class);
15 }


Note that the settings under the server node in the configuration file will not take effect when running on external Tomcat.These properties only affect embedded Tomcat.

Topics: Java Tomcat Spring Web Server network