title: Spring Boot application - not reading application.properties in Tomcat, but works under Spring Tool Suite
body: <p>I wrote a Spring Boot web application. The application runs under Spring Tool Suite fine, however, when I deploy in Tomcat, it is not able to read the configuration values. I <em>think</em> the difference is how the application being run. Any help or suggestions will be highly appreciated. I know this question has been asked many times - I did try all the solutions suggested, but did not have any luck.</p>
  
  <p>Here is the code/config I have:</p>
  
  <p><strong>TestApplication.java</strong></p>
  
  <pre><code>package com.example.test;
  
  import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
  import org.springframework.boot.SpringApplication;
  import org.springframework.boot.autoconfigure.SpringBootApplication;
  import org.springframework.boot.builder.SpringApplicationBuilder;
  import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
  import org.springframework.context.ApplicationContext;
  
  @SpringBootApplication
  public class TestApplication extends SpringBootServletInitializer
  {
    @Override
      protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
      {
          return application.sources(TestApplication.class);
      }
  
    public static void main(String[] args)
    {
      ApplicationContext context = SpringApplication.run(TestApplication.class, args);
  
      ServiceConfig bean = ServiceConfig.getServiceConfig();
      AutowireCapableBeanFactory factory = context.getAutowireCapableBeanFactory();
      factory.autowireBean( bean );
      factory.initializeBean( bean, "ServiceConfig" );
    }
  }
  </code></pre>
  
  <p><strong>TestController.java</strong></p>
  
  <pre><code>package com.example.test;
  
  import org.springframework.web.bind.annotation.RestController;
  import org.springframework.web.bind.annotation.GetMapping;
  
  @RestController
  public class TestController
  {
    @GetMapping(value = "/")
    public String index()
    {
      return "Hello from " + ServiceConfig.getServiceConfig().getName();
    }
  }
  </code></pre>
  
  <p><strong>ServletInitializer.java</strong></p>
  
  <pre><code>package com.example.test;
  
  import org.springframework.boot.builder.SpringApplicationBuilder;
  import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
  
  public class ServletInitializer extends SpringBootServletInitializer {
  
      @Override
      protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
          return application.sources(TestApplication.class);
      }
  
  }
  </code></pre>
  
  <p><strong>ServiceConfig.java</strong></p>
  
  <pre><code>package com.example.test;
  
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.stereotype.Component;
  
  @Component("ServiceConfig")
  public class ServiceConfig
  {
    static private ServiceConfig serviceConfig = null;
  
    @Value("${spring.application.name}")
    private String name;
  
    public String getName()
    {
      return name;
    }
  
    private ServiceConfig() {}
  
    public static ServiceConfig getServiceConfig()
    {
      if (serviceConfig == null) {
        serviceConfig = new ServiceConfig();
      }
  
      return serviceConfig;
    }
  }
  </code></pre>
  
  <p><strong>pom.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;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 https://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
      &lt;version&gt;2.3.0.RELEASE&lt;/version&gt;
      &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;
    &lt;/parent&gt;
    &lt;groupId&gt;com.example&lt;/groupId&gt;
    &lt;artifactId&gt;test&lt;/artifactId&gt;
    &lt;version&gt;1.0.0&lt;/version&gt;
    &lt;packaging&gt;war&lt;/packaging&gt;
    &lt;name&gt;test&lt;/name&gt;
    &lt;description&gt;Spring Boot Test Application&lt;/description&gt;
  
    &lt;properties&gt;
      &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
          &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
      &lt;java.version&gt;1.8&lt;/java.version&gt;
      &lt;start-class&gt;com.example.test.TestApplication&lt;/start-class&gt;
    &lt;/properties&gt;
  
    &lt;dependencies&gt;
      &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
        &lt;scope&gt;provided&lt;/scope&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
        &lt;scope&gt;test&lt;/scope&gt;
        &lt;exclusions&gt;
          &lt;exclusion&gt;
            &lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
            &lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
          &lt;/exclusion&gt;
        &lt;/exclusions&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;
  
    &lt;build&gt;
      &lt;plugins&gt;
    &lt;plugin&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
      &lt;configuration&gt;
        &lt;finalName&gt;test&lt;/finalName&gt;                   
      &lt;/configuration&gt;
    &lt;/plugin&gt;
      &lt;/plugins&gt;
    &lt;/build&gt;
  
  &lt;/project&gt;
  </code></pre>
  
  <p><strong>application.properties</strong></p>
  
  <pre><code>spring.application.name = Test-Service
  </code></pre>
  
  <p><strong>Deployment Steps:</strong></p>
  
  <pre><code>(1) Build the war file: mvn clean install
  (2) Copy the generated test.war under Tomcat /webapps directory.
  (3) Start tomcat using /bin/start.sh
  </code></pre>
  
  <p><strong>Issue:</strong></p>
  
  <p>When I browse <a href="http://localhost:8080/test" rel="nofollow noreferrer">http://localhost:8080/test</a>, I see the configuration parameter is not being populated:</p>
  
  <pre><code>Hello from null
  </code></pre>
  
  <p>However, I tried to run under Spring Tool Suite, I see the service running at  <a href="http://localhost:8080" rel="nofollow noreferrer">http://localhost:8080</a> and the code works:</p>
  
  <pre><code>Hello from Test-Service
  </code></pre>
  
  <hr>
  
  <hr>
  
  <h2>UPDATED WITH RESOLUTION</h2>
  
  <hr>
  
  <hr>
  
  <p>As pointed out by Andy Wilkinson, the main class was not being called by the war file, and therefore the the configurations were not loaded.</p>
  
  <p>The reason I added the adhoc initilization of the ServiceConfig bean is that the @Component annotation was not automatically loading the application.properties in the ServiceConfig class. Anyway, I finally used Java's @PostConstruct annotation that works both for independent Java application or war based Tomcat application:</p>
  
  <p>Here is the updated code:</p>
  
  <p><strong>TestApplication.java</strong></p>
  
  <pre><code>package com.example.test;
  
  import javax.annotation.PostConstruct;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
  import org.springframework.boot.SpringApplication;
  import org.springframework.boot.autoconfigure.SpringBootApplication;
  import org.springframework.boot.builder.SpringApplicationBuilder;
  import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
  import org.springframework.context.ApplicationContext;
  
  @SpringBootApplication
  public class TestApplication extends SpringBootServletInitializer
  {
      @Autowired
      private ApplicationContext appContext;
  
      @Override
      protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
      {
          return application.sources(TestApplication.class);
      }
  
      @PostConstruct
      public void init()
      {       
          ServiceConfig bean = ServiceConfig.getServiceConfig();
          AutowireCapableBeanFactory factory = appContext.getAutowireCapableBeanFactory();
          factory.autowireBean( bean );
          factory.initializeBean( bean, "ServiceConfig" );
      }
  
      public static void main(String[] args)
      {
          SpringApplication.run(TestApplication.class, args);     
  
      }
  }
  </code></pre>
  
  <p>Thanks @Andy Wilkinson again for your help!</p>
  
  <p>Best Regards,
  MN</p>