java – Spring Boot – Deployable War – ClassNotFoundException

I have been attempting to create a spring boot deployable war so that it can be deployed to a tomcat server (I would like to note that it runs fine as an executable jar). However, I have been running into the following exception which occurs on my Tomcat 9 server (I have one running within IntelliJ and another one running on a linux server, both throw the same exception):

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class (com.example.demo.DemoApplication); nested exception is java.lang.NoClassDefFoundError: org/springframework/context/annotation/AdviceMode

From my understanding, this lives in the spring-context jar, which is correctly being pulled into the build via maven. I created a super simple demo app with spring boot and I really can’t see why I would be running into this issue.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.4</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <groupId>com.example</groupId>
  <artifactId>demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>demo</name>
  <description>Demo project for Spring Boot</description>

  <properties>
    <java.version>11</java.version>
    <start-class>com.example.demo.DemoApplication</start-class>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.3.5</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.5</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <excludes>
            <exclude>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
            </exclude>
          </excludes>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

And here is the main application file:

DemoApplication.java

package com.example.demo;

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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication  extends SpringBootServletInitializer {
  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(DemoApplication.class);
  }
  public static void main(String() args) {
    SpringApplication.run(DemoApplication.class, args);
  }

  @RequestMapping(value = "/")
  public String hello() {
    return "Hello World from Tomcat";
  }
}

I am at a total loss as to why I’m hitting this ClassNotFoundException. Looking at the war file, I do see all the appropriate libraries in the WEB-INF/lib folder. The two files I pasted above are literally all the project I’m attempting to run is.

I have looked at this guide: Spring Boot Traditional Deployment

If I remove extends SpringBootServletInitializer, then the error goes away, but then I of course don’t really have a functional spring boot war file.