【问题标题】:How can I run Spring MVC application on Heroku?如何在 Heroku 上运行 Spring MVC 应用程序?
【发布时间】:2017-03-02 07:35:23
【问题描述】:

我在 Spring MVC 上有一个简单的应用程序,它在 IDEA 的 tomcat 7.0.72 上运行。我怎样才能在 Heroku 上运行这个应用程序(如果可能的话)。我有 Heroku 帐户,我确实在上面创建了应用程序。我使用 Maven 进行部署,使用 Git 将其推送到 Heroku。应用程序的文件将在下面。因此,当我通过 tomcat 在 localhost 上运行它时,它可以工作。但是当我把它推到heroku上时,我明白了:

应用程序错误:

应用程序发生错误,您的页面无法访问 服务。请稍后重试。如果您是应用程序所有者,请查看您的日志以了解详细信息。

这是我的 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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mardmitry</groupId>
    <artifactId>bestmuzon</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>BestMuzon</name>
    <!--<url>http://maven.apache.org</url>-->

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-framework-version>4.1.5.RELEASE</spring-framework-version>
        <tomcat.version>8.5.6</tomcat.version>
    </properties>

    <dependencies>

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

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

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

        <!--JSF (include "jsf-api" and "jsf-impl")-->
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.faces</artifactId>
            <version>2.2.10</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-logging-juli</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper-el</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jsp-api</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>com.github.jsimone</groupId>
            <artifactId>webapp-runner</artifactId>
            <version>8.0.30.2</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <url>https://bestmuzonproject.herokuapp.com/</url>
                    <!--<url>http://localhost:8080/manager/text</url>-->
                    <server>TomcatServer</server>
                    <path>/mkyongWebApp</path>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals><goal>copy</goal></goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>com.github.jsimone</groupId>
                                    <artifactId>webapp-runner</artifactId>
                                    <version>8.0.30.2</version>
                                    <destFileName>webapp-runner.jar</destFileName>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

我的应用程序的结构: Structure of app

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- Add Support for Spring -->
    <!-- Создает Spring Container, доступный всем сервлетам и фильтрам -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Обрабатывает все запросы. Центральное понятие-->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.form</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

主控制器:

package com.mardmitry.controllers;

import com.mardmitry.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MainController {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView main() {

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("userJSP", new User());
        modelAndView.setViewName("index");
        return modelAndView;
    }

    /*как только на index.jsp подтвердится форма
    <spring:form method="post"  modelAttribute="userJSP" action="check-user">,
    то попадем вот сюда
     */
    @RequestMapping(value = "/check-user")
    public ModelAndView checkUser(@ModelAttribute("userJSP") User user) {
        ModelAndView modelAndView = new ModelAndView();   
        modelAndView.setViewName("secondPage");
        modelAndView.addObject("userJSP", user);

        return modelAndView; 
    }
}

index.jsp:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
  <head>
    <title>Best Muzon</title>
  </head>
  <body>
  <spring:form method="post"  modelAttribute="userJSP" action="check-user">

      Name: <spring:input path="name"/> (path="" - указывает путь, используемый в modelAttribute=''. в нашем случае User.name)  <br/>
      Password: <spring:input path="password"/>   <br/>
      <spring:button>Next Page</spring:button>

  </spring:form>
  </body>
</html>

在 Git 中构建日志:

Counting objects: 359, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (282/282), done.
Writing objects: 100% (359/359), 20.70 MiB | 99.00 KiB/s, done.
Total 359 (delta 130), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Java app detected
remote: -----> Installing OpenJDK 1.8... done
remote: -----> Installing Maven 3.3.9... done
remote: -----> Executing: mvn -B -DskipTests clean dependency:list install
remote:        [INFO] Scanning for projects...
remote:        [INFO]
remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO] Building BestMuzon 1.0-SNAPSHOT
remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO]
remote:        [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ bestmuzon ---
remote:        [INFO] Deleting /tmp/build_90aea2b2f1ce2e21c7e6a87e78ae382d/target
remote:        [INFO]
remote:        [INFO] --- maven-dependency-plugin:2.3:list (default-cli) @ bestmuzon ---
remote:        [INFO]
remote:        [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ bestmuzon ---
remote:        [INFO] Using 'UTF-8' encoding to copy filtered resources.
remote:        [INFO] skip non existing resourceDirectory /tmp/build_90aea2b2f1ce2e21c7e6a87e78ae382d/src/main/resources
remote:        [INFO]
remote:        [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ bestmuzon ---
remote:        [INFO] Changes detected - recompiling the module!
remote:        [INFO] Compiling 2 source files to /tmp/build_90aea2b2f1ce2e21c7e6a87e78ae382d/target/classes
remote:        [INFO]
remote:        [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ bestmuzon ---
remote:        [INFO] Using 'UTF-8' encoding to copy filtered resources.
remote:        [INFO] skip non existing resourceDirectory /tmp/build_90aea2b2f1ce2e21c7e6a87e78ae382d/src/test/resources
remote:        [INFO]
remote:        [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ bestmuzon ---
remote:        [INFO] No sources to compile
remote:        [INFO]
remote:        [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ bestmuzon ---
remote:        [INFO] Tests are skipped.
remote:        [INFO]
remote:        [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ bestmuzon ---
remote:        [INFO] Building jar: /tmp/build_90aea2b2f1ce2e21c7e6a87e78ae382d/target/bestmuzon-1.0-SNAPSHOT.jar
remote:        [INFO]
remote:        [INFO] --- maven-dependency-plugin:2.3:copy (default) @ bestmuzon ---
remote:        [INFO] Configured Artifact: com.github.jsimone:webapp-runner:8.0.30.2:jar
remote:        [INFO] Copying webapp-runner-8.0.30.2.jar to /tmp/build_90aea2b2f1ce2e21c7e6a87e78ae382d/target/dependency/webapp-runner.jar
remote:        [INFO]
remote:        [INFO] --- maven-install-plugin:2.4:install (default-install) @ bestmuzon ---
remote:        [INFO] Installing /tmp/build_90aea2b2f1ce2e21c7e6a87e78ae382d/target/bestmuzon-1.0-SNAPSHOT.jar to /app/tmp/cache/.m2/repository/com/mardmitry/bestmuzon/1.0-SNAPSHOT/bestmuzon-1.0-SNAPSHOT.jar
remote:        [INFO] Installing /tmp/build_90aea2b2f1ce2e21c7e6a87e78ae382d/pom.xml to /app/tmp/cache/.m2/repository/com/mardmitry/bestmuzon/1.0-SNAPSHOT/bestmuzon-1.0-SNAPSHOT.pom
remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO] BUILD SUCCESS
remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO] Total time: 3.629 s
remote:        [INFO] Finished at: 2016-10-20T10:34:05+00:00
remote:        [INFO] Final Memory: 22M/171M
remote:        [INFO] ------------------------------------------------------------------------
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 70M
remote: -----> Launching...
remote:        Released v23
remote:        https://bestmuzonproject.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy.... done.
To https://git.heroku.com/bestmuzonproject.git
 + 8306e15...83a9a0c master -> master (forced update)

Heroku 日志:

2016-10-20T10:34:13.261601+00:00 heroku[api]: Deploy 83a9a0c by arxangel192@mail.ru
2016-10-20T10:34:13.261601+00:00 heroku[api]: Release v23 created by arxangel192@mail.ru
2016-10-20T10:34:13.409620+00:00 heroku[slug-compiler]: Slug compilation finished
2016-10-20T10:34:13.409611+00:00 heroku[slug-compiler]: Slug compilation started
2016-10-20T10:34:13.962566+00:00 heroku[web.1]: Restarting
2016-10-20T10:34:13.963376+00:00 heroku[web.1]: State changed from up to starting
2016-10-20T10:34:16.874279+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2016-10-20T10:34:17.556730+00:00 heroku[web.1]: Starting process with command `sh target/bin/webapp`
2016-10-20T10:34:18.183328+00:00 heroku[web.1]: Process exited with status 143
2016-10-20T10:34:19.795333+00:00 heroku[web.1]: State changed from starting to crashed
2016-10-20T10:34:19.796435+00:00 heroku[web.1]: State changed from crashed to starting
2016-10-20T10:34:19.682528+00:00 app[web.1]: Setting JAVA_TOOL_OPTIONS defaults based on dyno size. Custom settings will override them.
2016-10-20T10:34:19.686998+00:00 app[web.1]: sh: 0: Can't open target/bin/webapp
2016-10-20T10:34:19.777080+00:00 heroku[web.1]: Process exited with status 127
2016-10-20T10:34:23.291738+00:00 heroku[web.1]: Starting process with command `sh target/bin/webapp`
2016-10-20T10:34:24.945775+00:00 app[web.1]: Setting JAVA_TOOL_OPTIONS defaults based on dyno size. Custom settings will override them.
2016-10-20T10:34:24.946678+00:00 app[web.1]: sh: 0: Can't open target/bin/webapp
2016-10-20T10:34:25.024482+00:00 heroku[web.1]: State changed from starting to crashed
2016-10-20T10:34:25.009062+00:00 heroku[web.1]: Process exited with status 127
2016-10-20T10:34:57.262474+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=bestmuzonproject.herokuapp.com request_id=1acd63ba-7e38-4279-881c-2eb1a1708a63 fwd="178.94.207.167" dyno= connect= service= status=503 bytes=
2016-10-20T10:35:38.838802+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=bestmuzonproject.herokuapp.com request_id=cafaddfe-5c81-4d00-a47d-9c1111d6053b fwd="178.94.207.167" dyno= connect= service= status=503 bytes=

【问题讨论】:

  • 我看到并尝试这样做。但是应用程序错误。并在其中引导应用程序以不同的方式/类型编写。
  • 它在日志中显示什么?
  • 我将 Git 的构建日志添加到问题中。
  • 你添加了 procfile 吗?

标签: java spring maven jsp heroku


【解决方案1】:

Java Web 应用程序有(至少)两种部署方式:

这里详述第一个:

https://devcenter.heroku.com/articles/create-a-java-web-application-using-embedded-tomcat

这里详述第二个:

https://devcenter.heroku.com/articles/java-webapp-runner

您的 POM 中似乎混合了两种机制的元素:例如 webapp-runner 仅在第二种样式中是必需的。

消除这些冲突并检查配置。

【讨论】:

  • 那么,我无法创建可以通过tomcat和heroku在IDEA中运行的应用程序?
  • 我尝试用第二种方法。
  • 您可以从 IDEA 部署:devcenter.heroku.com/articles/… 或阅读 spring boot in action 第 8 章
  • 我想用 Spring 和映射而不是 servlet 构建应用程序
猜你喜欢
  • 1970-01-01
  • 2018-05-13
  • 1970-01-01
  • 2023-03-16
  • 2015-01-05
  • 2013-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
相关资源
最近更新 更多