无法将 Vaadin Java Spring 应用程序部署到 Heroku

Cannot deploy Vaadin Java Spring App to Heroku

我尝试将 vaadin 应用程序部署到 Heroku。我发现了几个问题,这些问题可以通过指定 Java 版本来解决。所以我也这样做了,似乎检测到了 Java 应用程序:

-----> Java app detected
-----> Installing JDK 11... done
-----> Installing Maven 3.6.2... done
-----> Executing Maven
       $ mvn -DskipTests clean dependency:list install

安装了几个东西,但最后我得到了以下错误:

[ERROR] Failed to execute goal com.vaadin:vaadin-maven-plugin:14.1.27:prepare-frontend (default) on project networker: 
       [ERROR] 
       [ERROR] ======================================================================================================
       [ERROR] Vaadin requires node.js & npm to be installed. Please install the latest LTS version of node.js (with npm) either by:
       [ERROR]   1) following the https://nodejs.org/en/download/ guide to install it globally. This is the recommended way.
       [ERROR]   2) running the following Maven plugin goal to install it in this project:
       [ERROR]   $ mvn com.github.eirslett:frontend-maven-plugin:1.7.6:install-node-and-npm
-DnodeVersion="v12.14.0" 
       [ERROR] 
       [ERROR] Note that in case you don't install it globally, you'll need to install it again for another Vaadin project.
       [ERROR] In case you have just installed node.js globally, it was not discovered, so you need to restart your system to get the path variables updated.
       [ERROR] ======================================================================================================
       [ERROR] -> [Help 1]
       [ERROR] 
       [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
       [ERROR] Re-run Maven using the -X switch to enable full debug logging.
       [ERROR] 
       [ERROR] For more information about the errors and possible solutions, please read the following articles:
       [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException !     ERROR: Failed to build app with Maven
       We're sorry this build is failing! If you can't find the issue in application code,
       please submit a ticket so we can help: https://help.heroku.com/  !     Push rejected, failed to compile Java app.  !     Push failed

有人知道如何处理这个错误吗?

这是我的 poml.xlm:

<?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>de.essling.networker</groupId>
    <artifactId>networker</artifactId>
    <name>networker</name>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>11</java.version>
        <vaadin.version>14.1.27</vaadin.version>

        <drivers.dir>${project.basedir}/drivers</drivers.dir>
        <drivers.downloader.phase>pre-integration-test</drivers.downloader.phase>
    </properties>

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

    <repositories>
        <!-- The order of definitions matters. Explicitly defining central here to make sure it has the highest priority. -->

        <!-- Main Maven repository -->
        <repository>
            <id>central</id>
            <url>https://repo.maven.apache.org/maven2</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <!-- Repository used by many Vaadin add-ons -->
        <repository>
            <id>Vaadin Directory</id>
            <url>https://maven.vaadin.com/vaadin-addons</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <!-- Main Maven repository -->
        <pluginRepository>
            <id>central</id>
            <url>https://repo.maven.apache.org/maven2</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <!-- Replace artifactId with vaadin-core to use only free components -->
            <artifactId>vaadin</artifactId>
            <exclusions>
                <!-- Webjars are only needed when running in Vaadin 13 compatibility mode -->
                <exclusion>
                    <groupId>com.vaadin.webjar</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.insites</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymer</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymerelements</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.vaadin</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.webcomponents</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring-boot-starter</artifactId>
            <exclusions>
                <!-- Excluding so that webjars are not included. -->
                <exclusion>
                    <groupId>com.vaadin</groupId>
                    <artifactId>vaadin-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-testbench</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <defaultGoal>spring-boot:run</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- Clean build and startup time for Vaadin apps sometimes may exceed
                     the default Spring Boot's 30sec timeout.  -->
                <configuration>
                    <wait>500</wait>
                    <maxAttempts>240</maxAttempts>
                </configuration>
            </plugin>

            <!--
                Take care of synchronizing java dependencies and imports in
                package.json and main.js files.
                It also creates webpack.config.js if not exists yet.
            -->
            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-frontend</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>

        <profile>
            <id>npm</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>com.github.eirslett</groupId>
                        <artifactId>frontend-maven-plugin</artifactId>
                        <!-- Use the latest released version:
                        https://repo1.maven.org/maven2/com/github/eirslett/frontend-maven-plugin/ -->
                        <version>1.9.1</version>
                        <executions>
                            <execution>
                                <id>install node and npm</id>
                                <goals>
                                    <goal>install-node-and-npm</goal>
                                </goals>
                                <!-- optional: default phase is "generate-resources" -->
                                <phase>generate-resources</phase>
                            </execution>
                        </executions>
                        <configuration>
                            <nodeVersion>v12.13.0</nodeVersion>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <!-- Production mode is activated using - Production -->
            <id>production</id>
            <properties>
                <vaadin.productionMode>true</vaadin.productionMode>
            </properties>

            <dependencies>
                <dependency>
                    <groupId>com.vaadin</groupId>
                    <artifactId>flow-server-production-mode</artifactId>
                </dependency>
            </dependencies>

            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <configuration>
                            <jvmArguments>-Dvaadin.productionMode</jvmArguments>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>com.vaadin</groupId>
                        <artifactId>vaadin-maven-plugin</artifactId>
                        <version>${vaadin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>build-frontend</goal>
                                </goals>
                                <phase>compile</phase>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <id>integration-tests</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>start-spring-boot</id>
                                <phase>pre-integration-test</phase>
                                <goals>
                                    <goal>start</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>stop-spring-boot</id>
                                <phase>post-integration-test</phase>
                                <goals>
                                    <goal>stop</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

                    <!-- Runs the integration tests (*IT) after the server is started -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <trimStackTrace>false</trimStackTrace>
                            <enableAssertions>true</enableAssertions>
                            <systemPropertyVariables>
                                <!-- Pass location of downloaded webdrivers to the tests -->
                                <webdriver.chrome.driver>${webdriver.chrome.driver}</webdriver.chrome.driver>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>

                    <plugin>
                        <groupId>com.lazerycode.selenium</groupId>
                        <artifactId>driver-binary-downloader-maven-plugin</artifactId>
                        <version>1.0.17</version>
                        <configuration>
                            <onlyGetDriversForHostOperatingSystem>true
                            </onlyGetDriversForHostOperatingSystem>
                            <rootStandaloneServerDirectory>
                                ${project.basedir}/drivers/driver
                            </rootStandaloneServerDirectory>
                            <downloadedZipFileDirectory>
                                ${project.basedir}/drivers/driver_zips
                            </downloadedZipFileDirectory>
                            <customRepositoryMap>
                                ${project.basedir}/drivers.xml
                            </customRepositoryMap>
                        </configuration>
                        <executions>
                            <execution>
                                <!-- use phase "none" to skip download step -->
                                <phase>${drivers.downloader.phase}</phase>
                                <goals>
                                    <goal>selenium</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>

    </profiles>
</project>

更新:

我有以下节点错误:

-----> Node.js app detected

-----> Creating runtime environment

       NPM_CONFIG_LOGLEVEL=error
       NODE_ENV=production
       NODE_MODULES_CACHE=true
       NODE_VERBOSE=false

-----> Installing binaries
       engines.node (package.json):  >=14.2.0
       engines.npm (package.json):   unspecified (use default)

       Resolving node version >=14.2.0...
       Downloading and installing node 14.2.0...
       Using default npm version: 6.14.4

-----> Installing dependencies
       Installing node modules
       npm ERR! code ENOENT
       npm ERR! syscall open
       npm ERR! path /tmp/build_80d39ca15258361b79fcfee6c11fad8c/node_modules/@vaadin/flow-deps/package.json
       npm ERR! errno -2
       npm ERR! enoent ENOENT: no such file or directory, open '/tmp/build_80d39ca15258361b79fcfee6c11fad8c/node_modules/@vaadin/flow-deps/package.json'
       npm ERR! enoent This is related to npm not being able to find a file.
       npm ERR! enoent 

       npm ERR! A complete log of this run can be found in:
       npm ERR!     /tmp/npmcache.1OllU/_logs/2020-05-11T13_48_17_942Z-debug.log
-----> Build failed

       We're sorry this build is failing! You can troubleshoot common issues here:
       https://devcenter.heroku.com/articles/troubleshooting-node-deploys

       Some possible problems:

       - Dangerous semver range (>) in engines.node
         https://devcenter.heroku.com/articles/nodejs-support#specifying-a-node-js-version

       Love,
       Heroku

 !     Push rejected, failed to compile Node.js app.
 !     Push failed

问题似乎是这个:

"@vaadin/flow-deps": "./target/frontend"

没有这一行我可以部署应用程序。那就是无法启动它,因为当然缺少 vaadin。

{
  "name": "no-name",
  "license": "UNLICENSED",
  "dependencies": {
    "@polymer/polymer": "3.2.0",
    "@webcomponents/webcomponentsjs": "^2.2.10",
    "@vaadin/flow-deps": "./target/frontend"
  },
  "devDependencies": {
    "webpack": "4.42.0",
    "webpack-cli": "3.3.10",
    "webpack-dev-server": "3.9.0",
    "webpack-babel-multi-target-plugin": "2.3.3",
    "copy-webpack-plugin": "5.1.0",
    "webpack-merge": "4.2.2",
    "raw-loader": "3.0.0",
    "compression-webpack-plugin": "3.0.1",
    "terser": "4.6.7"
  },
  "engines": {
    "node": "14.X"
  },
  "vaadinAppPackageHash": "Main dependencies updated, force install"
}

您还需要 heroku/nodejs buildpack,它将为您安装 node。您可以在应用仪表板中或通过 运行 heroku buildpacks:add heroku/nodejs -a your-app-name.

添加构建包

您需要 node 二进制文件才能将 Vaadin 14 客户端代码打包到 WAR javascript 包中。请参阅 https://github.com/mvysny/vaadin14-embedded-jetty#heroku-integration 了解如何完成该操作。简而言之,您需要一个用于 Heroku 的自定义 Maven settings.xml 文件,其中包含两个配置文件:production 和 heroku;触发 heroku 配置文件将启用 com.github.eirslett:frontend-maven-plugin,这将为您安装节点。

或者您可以尝试 Vaadin 14.2.0.beta1,它可以在节点丢失时自动下载。也就是说,您仍然需要自定义 settings.xml 文件来至少启用生产模式。

我一直在寻找 gradle 的解决方案,但是太难了。 把它保存在这里以防它对某人有帮助:

只需在您的 build.gradle 文件中添加 vaadin.productionMode = true