Spring Boot application gives 404 when deployed to Tomcat but works with embedded server
Asked Answered
D

9

61

Guided by Serving Web Content with Spring MVC, I'm creating a Spring Boot web application that I can run using both the embedded Tomcat instance as well as on a standalone Tomcat 8 server.

The application works as expected when executed as java -jar adminpage.war and I see the expected outcome when I visit http://localhost:8080/table. However, when I deploy to a Tomcat 8 server (by dropping adminpage.war into the webapps directory), I get a 404 error when I visit https://myserver/adminpage/table.

The catelina.log and localhost.log files contain nothing helpful on the Tomcat server.

Can anyone suggest where I've made a misconfiguration? I've not had the same problems in the past when deploying RESTful services with Spring Boot, but this is my first foray into a web application.

My application files:

src/main/java/com/.../Application.java

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

src/main/java/com/.../MainController.java

@Controller
public class MainController {

    @RequestMapping("/table")
    public String greeting(Model model) {
        model.addAttribute("name", "Fooballs");
        return "table";
    }
}

src/main/resources/templates/table.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <p th:text="'Hello, ' + ${name} + '!'" />
</body>
</html>

pom.xml

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.foo</groupId>
  <artifactId>adminpage</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </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-thymeleaf</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <optional>true</optional>
    </dependency>
  </dependencies>

  <properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>


  <build>
    <finalName>adminpage</finalName>

    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>
Derange answered 19/9, 2016 at 7:19 Comment(3)
Does your application contains web.xml?Gerthagerti
@SergeyBespalov I don't think it needs one with Spring Boot. See my answer below - I had forgotten to adjust my Application.java file.Derange
you're right it's not necessary, but still can be used with Spring BootGerthagerti
D
100

I had forgotten to tweak my Application.java file to extend SpringBootServletInitializer and override the configure method.

Corrected file:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
  public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
  }

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
      return builder.sources(Application.class);
  }
}

Hat tip to https://mtdevuk.com/2015/07/16/how-to-make-a-spring-boot-jar-into-a-war-to-deploy-on-tomcat/ for pointing out my mistake.

More info at Create a deployable war file in Spring Boot Official docs.

Derange answered 19/9, 2016 at 7:36 Comment(2)
Thanks a lot but now the class is depricated ;)Birdiebirdlike
mayank, can you tell the latest way?Paleo
E
20

As of August 2021 . If anyone facing this issue in Tomcat 10 server, just read in the below post that Spring boot won't work in Tomcat 10. https://github.com/spring-projects/spring-boot/issues/22414

I had faced this issue and switching to an previous version, which resolved the problem.

Ester answered 25/8, 2021 at 5:36 Comment(3)
Very important information, was struggling for a while, thanks Dipu!Cand
I'm using Tomcat 9 and still facing this issue.Kakalina
Thanks for the info, I've wasted several hours of my life with this Tomcat BSLafave
C
4

Downgrading Tomcat from version 10 to 9 did the trick for me. Update January 2022, apparently tomcat 10 still does not support spring-boot. As mentioned by Dipu over here, https://mcmap.net/q/322257/-spring-boot-application-gives-404-when-deployed-to-tomcat-but-works-with-embedded-server

Cyanocobalamin answered 21/1, 2022 at 12:45 Comment(0)
M
2

In case anyone having same problem while using sprint boot in the IntelliJ community edition. You just need to put your main class in the main package (com.xyx) don't put it in any subpackage which is created inside com.xyx.

Moisture answered 20/10, 2019 at 6:52 Comment(0)
V
1

Quoting dieter's answer on another SO question:

You war file name is priz-0.5.war. So the context name is also priz-0.5. You have to call for example http://localhost:8080/priz-0.5

If you want to call it like http://localhost:8080/ just rename the war-File to ROOT.war

Villasenor answered 1/6, 2022 at 5:23 Comment(0)
R
1

I had the same issue and it turned out that I had compiled the app for java 11, while my server was running java 8. Once I upgraded to java 11 it worked fine. It was tricky because I there was absolutely nothing in Tomcats log that indicated that issue.

Ruggles answered 30/11, 2022 at 16:36 Comment(0)
B
0

Just add the route in the controller annotation, something like this: @RestController @RequestMapping(value = "/")

Brokenhearted answered 1/7, 2020 at 0:52 Comment(0)
W
0

For me, the Spring boot wasn't work with tomcat 10. I changed for 9 version and it worked.

Whitefly answered 9/5, 2022 at 3:12 Comment(0)
B
0

I had the same problem but everything was fine with my SpringBootConfiguration I finally found out why I had a 404

I just removed maven-dependency-plugin in build->plugin from my pom.xml

<!--
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.3.0</version>
        </plugin>
-->

This removal allowed me to finally test my war file on a tomcat9 with success and still allow me to test via mvnw

May this help someone

Blindfold answered 6/10, 2022 at 14:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.