Search code examples
eclipsemavenspring-mvctomcattomcat7

Maven API does not respond when deployed on Server (Tomcat 7)


Okay, so I'll explain briefly. I made an API with Maven, Eclipse and Spring MVC, and it works perfectly when running with "tomcat7:run". (Port 9090)

The problem comes when running the server, and deploying the API there. The server works like a charm, http//:localhost:8080 works perfectly, the problem comes when I try to make requests to the API, because it seems that it doesn't exist, as it doesn't respond to any request (404 every time).

The project is deployed, if I watch it from managers/html I can see that it's running, so I've got no clue to what could be the problem. I've tried to search and search for the error but reached my limit. Thanks in advance!

If you want to see any code just ask, because I don't know what code to upload in this case.

This is one of the controller classes:

package com.autentia.spring.controller;

import com.autentia.spring.model.Course;
import com.autentia.spring.service.CourseService;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@CrossOrigin("*")
@RestController
public class CourseController {

    @Autowired
    private CourseService courseService;

    @RequestMapping(value = "/", method = RequestMethod.GET, headers = "Accept=application/json") //This method was a get, post is just for testing
    public ResponseEntity<String> welcome(@RequestBody String body) {
        System.out.println("In the UserController::index");
        return new ResponseEntity<>("It works!", HttpStatus.OK);
    }

    @RequestMapping(value = "/courses", method = RequestMethod.GET)
    public ResponseEntity<List<Course>> users() {
        System.out.println("Getting all courses");
        List<Course> list = courseService.getAllCourses();
        System.out.println("List: " + list);
        return ResponseEntity.ok().body(list);
    }

    @RequestMapping(value = "/courses", method = RequestMethod.POST, headers = "Accept=application/json")
    public ResponseEntity<String> insertCourse(@RequestBody Course course) {
        System.out.println("Inserting course: " + course);
        course.setId((long)0);
        // boolean teacherSaved = teacherService.insertTeacher(teacher);
        courseService.insertCourse(course);
        return new ResponseEntity(course.getId(), HttpStatus.OK);
    }
}

This is the log when deploying the app:

May 05, 2019 12:29:18 PM org.apache.catalina.core.ApplicationContext log
INFO: HTMLManager: list: Listing contexts for virtual host 'localhost'
May 05, 2019 12:29:48 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive /usr/local/apache-tomcat-7.0.94/webapps/course-catalogue-0.0.1-SNAPSHOT.war
May 05, 2019 12:29:48 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deployment of web application archive /usr/local/apache-tomcat-7.0.94/webapps/course-catalogue-0.0.1-SNAPSHOT.war has finished in 50 ms
May 05, 2019 12:29:48 PM org.apache.catalina.core.ApplicationContext log
INFO: HTMLManager: list: Listing contexts for virtual host 'localhost'

pom.xml file:

<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>autentia</groupId>
    <artifactId>course-catalogue</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>5.1.6.RELEASE</spring.version>
        <mybatis.version>3.2.8</mybatis.version>
        <mybatisspring.version>1.1.1</mybatisspring.version>
        <mysql.version>5.1.47</mysql.version>
        <jackson.version>2.9.5</jackson.version>
        <javax-servlet.version>3.1.0</javax-servlet.version>
        <maven.version>3.6.1</maven.version>
        <hibernate.version>5.2.11.Final</hibernate.version>
        <c3p0.version>0.9.5.2</c3p0.version>
        <file-upload.version>1.3.1</file-upload.version>
        <angular.project.location>front-end-angular</angular.project.location>
        <angular.project.nodeinstallation>node_installation</angular.project.nodeinstallation>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- Spring MVC Dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Hibernate ORM -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <!-- Hibernate-C3P0 Integration -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>${c3p0.version}</version>
        </dependency>

        <!-- MyBatis Dependencies -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.7</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.2</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

        <!-- MySQL connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>

        <!-- Servlet Dependency -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${javax-servlet.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat</artifactId>
            <version>7.0.94</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-utils</artifactId>
            <version>1.1</version>
        </dependency>

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${file-upload.version}</version>
        </dependency>

        <!-- Front End Dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
    <build>
        <finalName>${artifactId}</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.version}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <url>http://localhost:8080/manager/html</url>
                    <update>true</update>
                    <username>admin</username>
                    <password>admin</password>
                    <port>8080</port>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.1.1</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.7</version>
            </plugin>

            <!-- Front End Plugin -->
            <plugin>
                <groupId>com.github.eirslett</groupId>
                <artifactId>frontend-maven-plugin</artifactId>
                <version>1.6</version>
                <configuration>
                    <workingDirectory>${angular.project.location}</workingDirectory>
                    <installDirectory>${angular.project.nodeinstallation}</installDirectory>
                </configuration>
                <executions>
                    <!-- It will install nodejs and npm -->
                    <execution>
                        <id>install node and npm</id>
                        <goals>
                            <goal>install-node-and-npm</goal>
                        </goals>
                        <configuration>
                            <nodeVersion>v8.11.4</nodeVersion>
                        </configuration>
                    </execution>

                    <!-- It will execute command "npm install" inside "/e2e-angular" directory -->
                    <execution>
                        <id>npm install</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <configuration>
                            <arguments>install</arguments>
                        </configuration>
                    </execution>
                    <!-- It will execute command "npm build" inside "/e2e-angular" directory 
                        to clean and create "/dist" directory -->
                    <execution>
                        <id>npm build</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <configuration>
                            <arguments>run build</arguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- Plugin to copy the content of /angular/dist/ directory to output 
                directory (ie/ /target/transactionManager-1.0/) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.4.2</version>
                <executions>
                    <execution>
                        <id>default-copy-resources</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <overwrite>true</overwrite>
                            <!-- This folder is the folder where your angular files will be copied 
                                to. It must match the resulting war-file name. So if you have customized 
                                the name of war-file for ex. as "app.war" then below value should be ${project.build.directory}/app/ 
                                Value given below is as per default war-file name -->
                            <outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>${project.basedir}/${angular.project.location}/dist</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <fork>true</fork>
                    <executable>/usr/local/java/jdk1.8.0_212/bin/javac</executable>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

I tried the following URLs:

http://localhost:8080/course-catalogue-0.0.1-SNAPSHOT/courses

http://localhost:8080/course-catalogue-0.0.1-SNAPSHOT

http://localhost:8080/course-catalogue/courses

http://localhost:8080/course-catalogue

http://localhost:8080/course-catalogue-0.0.1-SNAPSHOT/course-catalogue/courses

http://localhost:8080/course-catalogue/course-catalogue/courses

Solution

  • Okay, so I solved it. After lots of tears, after loads of juggling with the pom.xml, it worked.

    pom.xml is still a mistery to me, but I'll post what I have for people that are in the same situation as me :) Keep in mind that I am using Angular in my Maven project, that's the reason why there are some node plugins and such.

    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>autentia</groupId>
        <artifactId>course-catalogue</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <properties>
            <failOnMissingWebXml>false</failOnMissingWebXml>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <spring.version>5.1.6.RELEASE</spring.version>
            <mybatis.version>3.2.8</mybatis.version>
            <mybatisspring.version>1.1.1</mybatisspring.version>
            <mysql.version>5.1.47</mysql.version>
            <jackson.version>2.9.5</jackson.version>
            <javax-servlet.version>3.1.0</javax-servlet.version>
            <maven.version>3.6.1</maven.version>
            <hibernate.version>5.2.11.Final</hibernate.version>
            <c3p0.version>0.9.5.2</c3p0.version>
            <junit.version>4.11</junit.version>
            <file-upload.version>1.3.1</file-upload.version>
            <angular.project.location>front-end-angular</angular.project.location>
            <angular.project.nodeinstallation>node_installation</angular.project.nodeinstallation>
            <java.home>/usr/local/java/jdk1.8.0_212</java.home>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>javax</groupId>
                <artifactId>javaee-web-api</artifactId>
                <version>6.0</version>
                <scope>provided</scope>
            </dependency>
    
            <!-- Spring MVC Dependencies -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <!-- MyBatis Dependencies -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.2.7</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>1.2.2</version>
                <type>jar</type>
                <scope>compile</scope>
            </dependency>
    
            <!-- MySQL connector -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
    
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson.version}</version>
            </dependency>
    
            <!-- Servlet Dependency -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>${javax-servlet.version}</version>
                <scope>provided</scope>
            </dependency>
    
            <dependency>
                <groupId>commons-lang</groupId>
                <artifactId>commons-lang</artifactId>
                <version>2.1</version>
            </dependency>
            <dependency>
                <groupId>org.codehaus.plexus</groupId>
                <artifactId>plexus-utils</artifactId>
                <version>1.1</version>
            </dependency>
    
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>${file-upload.version}</version>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                    <configuration>
                        <verbose>true</verbose>
                        <fork>true</fork>
                        <executable>${java.home}</executable>
                        <compilerVersion>1.8</compilerVersion>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <url>http://localhost:8080/manager/text</url>
                        <server>TomcatServer</server>
                        <path>/course-catalogue</path>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.3</version>
                </plugin>
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>2.7</version>
                </plugin>
    
                <!-- Front End Plugin -->
                <plugin>
                    <groupId>com.github.eirslett</groupId>
                    <artifactId>frontend-maven-plugin</artifactId>
                    <version>1.6</version>
                    <configuration>
                        <workingDirectory>${angular.project.location}</workingDirectory>
                        <installDirectory>${angular.project.nodeinstallation}</installDirectory>
                    </configuration>
                    <executions>
                        <!-- It will install nodejs and npm -->
                        <execution>
                            <id>install node and npm</id>
                            <goals>
                                <goal>install-node-and-npm</goal>
                            </goals>
                            <configuration>
                                <nodeVersion>v8.11.4</nodeVersion>
                            </configuration>
                        </execution>
    
                        <!-- It will execute command "npm install" inside "/e2e-angular" directory -->
                        <execution>
                            <id>npm install</id>
                            <goals>
                                <goal>npm</goal>
                            </goals>
                            <configuration>
                                <arguments>install</arguments>
                            </configuration>
                        </execution>
                        <!-- It will execute command "npm build" inside "/e2e-angular" directory 
                            to clean and create "/dist" directory -->
                        <execution>
                            <id>npm build</id>
                            <goals>
                                <goal>npm</goal>
                            </goals>
                            <configuration>
                                <arguments>run build</arguments>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
    
                <!-- Plugin to copy the content of /angular/dist/ directory to output 
                    directory (ie/ /target/transactionManager-1.0/) -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>2.4.2</version>
                    <executions>
                        <execution>
                            <id>default-copy-resources</id>
                            <phase>process-resources</phase>
                            <goals>
                                <goal>copy-resources</goal>
                            </goals>
                            <configuration>
                                <overwrite>true</overwrite>
                                <!-- This folder is the folder where your angular files will be copied 
                                    to. It must match the resulting war-file name. So if you have customized 
                                    the name of war-file for ex. as "app.war" then below value should be ${project.build.directory}/app/ 
                                    Value given below is as per default war-file name -->
                                <outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/</outputDirectory>
                                <resources>
                                    <resource>
                                        <directory>${project.basedir}/${angular.project.location}/dist</directory>
                                    </resource>
                                </resources>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <fork>true</fork>
                        <executable>/usr/local/java/jdk1.8.0_212/bin/javac</executable>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    

    It is also important (although I don't know if this played a role in the correct deployment and functioning of the api) that you write the following into {MAVEN_HOME}/conf/settings.xml:

    <settings>
       <servers>
          <server>
            <id>TomcatServer</id>
            <username>admin</username>
            <password>admin</password>
         </server>
      </servers>
    </settings>
    

    Hope it helps someone!