0
votes

I have a simple RestController application -

@RestController
public class GreetingController {

    private static final Logger logger = LogManager.getLogger(GreetingController.class);

    @RequestMapping("/greeting")
    public ResponseEntity<GreetingResponse> greeting(@RequestParam(value = "name", defaultValue = "World") String name) throws ServiceException, Exception {
        logger.info("Received Request. Name: " + name);

It works fine on SpringBoot (http://localhost:8080/greeting), but when I create a WAR and deploy it on Tomcat (9.0.2), it throws a 404.

Application is deployed fine and I can hit a static HTML page in the application, so my context path is correct.

What could I be missing?

Here is my gradle tasks -

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('com.jayway.jsonpath:json-path')
    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
    compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'    
}

war {

    archiveName = "ROOT.war"
    manifest {attributes "Implementation-Version": "${version}"}
}

I have zip of my whole application here, if anyone is curious.

2

2 Answers

1
votes

Found the issue. My application had to extend SpringBootServletInitializer

@SpringBootApplication
public class Application  extends SpringBootServletInitializer {
0
votes

Your answer is correct, I just wanted to add on it, that if you have the requirement where you need to create a war file for your application and deploy it on an external app server like Tomcat or IBM Liberty, it is is best you disable the inbuilt tomcat starter when deploying it in external App servers. This can be done via using profiles tag in your POM file and using the exclusion tag to specify that you do not need "spring-boot-starter-tomcat"

Our POM looks like this

<groupId>com.anz.tpp</groupId>
<artifactId>example-project</artifactId>
<packaging>war</packaging>
<version>1.0.0-SNAPSHOT</version>
<name>Example Project</name>

<!-- Versions -->
<properties>
    <apache.camel.version>X.X.X</apache.camel.version>
    <junit.version>X.X</junit.version>
</properties>


<!-- Spring Boot Parent -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
    <relativePath />
</parent>

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <activatedProperties>dev</activatedProperties>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-logging</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-tomcat</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

        </dependencies>

        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>false</filtering>
                </resource>
            </resources>

            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                            <configuration>
                                <skip>true</skip>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>

            </plugins>
        </build>
    </profile>

    <profile>
        <id>local</id>
        <properties>
            <activatedProperties>local</activatedProperties>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-logging</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
        .......

    </profile>
</profiles>

Not sure if this is really a concern at your end, but it is best to operate under two profiles where you use one profile to run your project through an IDE like intelliJ or Eclipse and other way, you can use the dev profile to build your package by specifying "mvn clean install -U -P dev" to deploy the war file in an external appserver like tomcat or IBM Liberty.

My apologies if you have already figured it out, just that this helped me during my starting stages of my spring-boot project. Hope this helps!