Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Openshift Spring MVC Tomcat application's deployed path returns 404

I am running a Tomcat7 application using Spring MVC on OpenShift under the domain: financial-datasite.rhcloud.com. I run and test the application locally using a Tomcat server and later push it to the remote repository. Currently, there's only a HomePage and a button underneath redirecting to a different page. When testing locally, both pages display contents as expected. However, when deployed to the remote server, only the HomePage is displayed, and on clicking the button, I get an HTTP 404 error. I have come across various similar questions here, but none of them have helped so far. I have played around configuring the web.xml, pom.xml, servlet-context.xml, and the controller files. However, none of those have helped. I have also been checking the tail files and logs to monitor what's happening, which suggests that the remote server is accessing some 'printWelcome' method (which doesn't even exist in my project) in the controller class for the second page:

INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/Sectors],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.spring.mvc.SectorController.printWelcome(org.springframework.ui.ModelMap)

Here is my project structure. In my localhost, the default page is run as localhost:8181/mvc/ and the second page is run as http://localhost:8181/mvc/Sectors. Similarly, post deployment, the home page is run as http://financial-datasite.rhcloud.com and the second page executed as http://financial-datasite.rhcloud.com/Sectors, which throws a 404 error for /WEB-INF/views/hello.jsp, which, again, doesn't even exist in my project directory. Another thing I observed in the log files are that the code is likely not hitting the SectorController class as I have coded for print commands to be logged, which aren't really getting logged into the console when the page is requested from the deployed site. I am quite unsure about which files are being run on the remote server and if there are any configuration issues that I am unaware of. Following are my web.xml, pom.xml, servlet-context.xml, Sectors.jsp, Google-Maps.js from where I've called the new page to load), and SectorController.java (which is the controller file for the second page). Apologies for a lengthy question, please let me know if you require any more information. Any help would be appreciated, thanks.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

  <display-name>Financial Data Site</display-name>

  <servlet>
    <servlet-name>financial</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>financial</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <welcome-file-list>
    <welcome-file>index</welcome-file>
  </welcome-file-list>

</web-app>

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 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.spring</groupId>
    <artifactId>mvc</artifactId>
    <name>SpringMVC</name>
    <packaging>war</packaging>
    <version>1.0.0-BUILD-SNAPSHOT</version>

    <properties>
        <java-version>1.6</java-version>
        <org.springframework-version>3.1.1.RELEASE</org.springframework-version>
        <org.aspectj-version>1.6.10</org.aspectj-version>
        <org.slf4j-version>1.6.6</org.slf4j-version>

        <!-- Newly Added from here -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.6</maven.compiler.source>
        <maven.compiler.target>1.6</maven.compiler.target>
    </properties>

    <repositories>
        <repository>
            <id>eap</id>
            <url>http://maven.repository.redhat.com/techpreview/all</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>eap</id>
            <url>http://maven.repository.redhat.com/techpreview/all</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
    <!-- Till here -->

    <dependencies>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
            <exclusions>
                <!-- Exclude Commons Logging in favor of SLF4j -->
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                 </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <!-- MySQL database driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.6.10.Final</version>
        </dependency>

        <!-- AspectJ -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj-version}</version>
        </dependency>   

        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${org.slf4j-version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.mail</groupId>
                    <artifactId>mail</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.jms</groupId>
                    <artifactId>jms</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jdmk</groupId>
                    <artifactId>jmxtools</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jmx</groupId>
                    <artifactId>jmxri</artifactId>
                </exclusion>
            </exclusions>
            <scope>runtime</scope>
        </dependency>

        <!-- @Inject -->
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>

        <!-- JSTL -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
            <scope>compile</scope>
        </dependency>

        <!-- Tag Library -->
        <dependency>
          <groupId>taglibs</groupId>
          <artifactId>standard</artifactId>
          <version>1.1.2</version>
          <scope>compile</scope>
        </dependency>

        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <!-- When built in OpenShift the 'openshift' profile will be 
                used when invoking mvn. -->
            <!-- Use this profile for any OpenShift specific customization 
                your app will need. -->
            <!-- By default that is to put the resulting archive into the 
                'deployments' folder. -->
            <!-- http://maven.apache.org/guides/mini/guide-building-for-different-environments.html -->
            <id>openshift</id>
            <build>
            <finalName>financial</finalName>
                <plugins>
                    <plugin>
                        <artifactId>maven-war-plugin</artifactId>
                        <version>2.4</version>
                        <configuration>
                            <outputDirectory>webapp</outputDirectory>
                            <warName>ROOT</warName>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <annotation-driven />

    <context:component-scan base-package="com.spring.mvc" />

    <resources mapping="/resources/**" location="/resources/" />

    <beans:bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

</beans:beans>

Sectors.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ page session="false"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Sectors</title>
</head>

<body>
    <h1>Message</h1>
    <c:if test="${not empty Sectors}">

        <ul>
            <c:forEach var="_SectorNames" items="${Sectors}">
                <li>${_SectorNames}</li>
            </c:forEach>
        </ul>

    </c:if>
</body>

</html>

Google-Maps.js: following snippet only contains the function used to create a div section on the map and to call a new page on a new window

function HomeControl(controlDiv, map)
{
      // Set CSS for the control border.
      var _ControlUI = document.createElement('div');
      _ControlUI.style.backgroundColor = '#fff';
      _ControlUI.style.border = '2px solid #fff';
      _ControlUI.style.borderRadius = '3px';
      _ControlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
      _ControlUI.style.cursor = 'pointer';
      _ControlUI.style.marginBottom = '22px';
      _ControlUI.style.textAlign = 'center';
      _ControlUI.title = 'Click to filter by Sectors';
      controlDiv.appendChild(_ControlUI);

      // Set CSS for the control interior.
      var _ControlText = document.createElement('div');
      _ControlText.style.color = 'rgb(25,25,25)';
      _ControlText.style.fontFamily = 'Roboto,Arial,sans-serif';
      _ControlText.style.fontSize = '12px';
      _ControlText.style.lineHeight = '38px';
      _ControlText.style.paddingLeft = '5px';
      _ControlText.style.paddingRight = '5px';
      _ControlText.innerHTML = '<strong>View by Sectors</strong>';
      _ControlUI.appendChild(_ControlText);

      // Setup the click event listeners, also calls Sectors page on a new window
      google.maps.event.addDomListener(_ControlUI, 'click', function() {
          //add code here to redirect to Sectors page
          var _Window = window.open('/mvc/Sectors', '__blank');
          _Window.focus();
      });
}

SectorController.java

    package com.spring.mvc;

    import java.text.DateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Locale;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;

    import com.spring.dao.impl.SectorDAOImpl;
    import com.spring.model.Sector;

    @Controller
    public class SectorController {

        private static final Logger logger = LoggerFactory.getLogger(SectorController.class);

        @RequestMapping(value = "/Sectors", method = {RequestMethod.HEAD, RequestMethod.GET})
        public ModelAndView DisplaySectors(Locale locale, Model model) {

            logger.info("Welcome home! You are in: {}.", locale);

            Date date = new Date();
            DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

            String formattedDate = dateFormat.format(date);

            model.addAttribute("serverTime", formattedDate );

            SectorDAOImpl _SectorDAOImpl = new SectorDAOImpl();
            List<Sector> _Sectors = _SectorDAOImpl.GetByID();       
            List<String> _SectorNames = new ArrayList<String>();

            for( Sector sector : _Sectors) {
                _SectorNames.add(sector.getSectorName());
            }

            ModelAndView _ModelAndView = new ModelAndView("Sectors");
            _ModelAndView.addObject("Sectors", _SectorNames);

            return _ModelAndView;
        }
}
like image 528
Computer Scientist Avatar asked Apr 26 '15 18:04

Computer Scientist


1 Answers

  1. As Jessai noted in a comment,

    var _Window = window.open('/mvc/Sectors', '__blank');
    

    Do not use your project name explicitly! There are a ways to get your context name, such as request.getContextPath() method of HttpServletRequest.

    In this case with a hard-coded URL string I think that you can use relative URL, just 'Sectors' or './Sectors'.

    References:

    • https://developer.mozilla.org/en-US/docs/Web/API/Window/open
    • http://www.w3.org/TR/html5/browsers.html#dom-open
  2. '__blank' : you meant '_blank' ?

  3. By the way:

    You are deploying on Tomcat 7, so you can declare adherence to Servlet 3.0 specification instead of 2.5 in your web.xml file.

    See the following to disable components scanning at startup:
    https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Configure_your_web_application

  4. On

    INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/Sectors],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.spring.mvc.SectorController.printWelcome(org.springframework.ui.ModelMap)
    

    If your class file does not match your source code, it means that your code has not been compiled. Delete your compiled classes (e.g. use mvn clean) and try again.

    If you are curious, you can unpack your war file with any ZIP archiver application and look what is actually there.

  5. Do you or our company own the domain name of http://spring.com web site? If not, DO NOT use package name com.spring and do not use <groupId>com.spring</groupId>. Those names do not belong to you. They are someone else's property.

  6. On

    <org.springframework-version>3.1.1.RELEASE</org.springframework-version>
    

    If you are using 3.x, why not the current 3.2.12.RELEASE in 3.x series, or better the last 4.1.6.RELEASE? Spring Framework 3.1.x has reached end of life and is no more supported.

like image 166
Konstantin Kolinko Avatar answered Nov 07 '22 23:11

Konstantin Kolinko