Jetty 无法在 appengineFlexible 中启动 Spring Boot 应用程序

问题描述 投票:0回答:1

注意:这是一个交叉帖子,因为我不确定这是技术问题还是错误,因此可以在here

找到该错误

几周前,我编写了一个原型,用于向我们的 appengine 项目添加灵活的环境服务,该项目主要是标准环境服务。该原型基于 java 快速入门示例“HelloworldSpringBoot”并进行了一些细微修改。

在原型取得成功后,我转向了该服务的更多生产代码集,开发了几周,并尝试在 4 天前的 1 月 12 日进行部署。该应用程序拒绝启动,在多次尝试将应用程序简化为单一路线后,我无法启动该应用程序。

我切换回原型代码,部署到代码正在运行的原始项目,并且看到应用程序未启动的相同行为。

没有任何错误消息可以指出,因此我将在此处列出一些可能是罪魁祸首的错误消息。

第一个是最明显的,但可能是一个通用的包罗万象的:

Exception in thread "main" java.lang.IllegalStateException: No Available Context
        at com.google.cloud.runtimes.jetty9.DeploymentCheck.lifeCycleStarted(DeploymentCheck.java:46)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.setStarted(AbstractLifeCycle.java:179)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
        at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1511)
        at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1438)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1437)

下一个发生在启动的更早阶段,但看起来是良性的:

javax.servlet.ServletException: Not running on Jetty, JSR-356 support unavailable at org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.onStartup(WebSocketServerContainerInitializer.java:193) at org.eclipse.jetty.plus.annotation.ContainerInitializer.callStartup(ContainerInitializer.java:140) at org.eclipse.jetty.annotations.ServletContainerInitializersStarter.doStart(ServletContainerInitializersStarter.java:63) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:329) at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1501) at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1463) at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:785) at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:261) at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:41) at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:188) at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:502) at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:150) at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180) at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:447) at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64) at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:610) at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:529) at org.eclipse.jetty.util.Scanner.scan(Scanner.java:392) at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:150) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:564) at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:239) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131) at org.eclipse.jetty.server.Server.start(Server.java:452) at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113) at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113) at org.eclipse.jetty.server.Server.doStart(Server.java:419) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1511) at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1438) at java.security.AccessController.doPrivileged(Native Method) at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1437)

然后就是这个家伙,就在上一个之后发生:

org.eclipse.jetty.webapp.WebAppContext: Failed startup of context o.e.j.w.WebAppContext@7e0b0338{/,file:///var/lib/jetty/webapps/root/,UNAVAILABLE}{/root.war}

此外,以下是相关文件:

app.yaml:

runtime: java
env: flex

runtime_config:  # Optional
  jdk: openjdk8

service: service2

handlers:
- url: /.*
  script: this field is required, but ignored

manual_scaling:
  instances: 1

构建.gradle:

buildscript {      // Configuration for building
    ext {
        springBootVersion = '1.5.9.RELEASE'
    }
    repositories {
        jcenter()      // Bintray's repository - a fast Maven Central mirror & more
        mavenCentral()
        maven { url 'https://repo.spring.io/libs-snapshot' }
    }
    dependencies {
        classpath 'com.google.cloud.tools:appengine-gradle-plugin:+'
        classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
    }
}

repositories {   // repositories for JARs you access in your code
    maven {
        url 'https://maven-central.storage.googleapis.com'             // Google's mirror of Maven Central
    }

    maven {
        url "http://repo.spring.io/libs-snapshot"
    }

    jcenter()
    mavenCentral()
}

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'com.google.cloud.tools.appengine'
apply plugin: 'org.springframework.boot'

dependencies {

    // Add your dependencies here.
    compile "org.springframework.boot:spring-boot-starter-web", { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' }
    compile (
            "org.springframework.boot:spring-boot-starter-actuator",
            "org.springframework.boot:spring-boot-starter-jetty"
    )
    testCompile (
            "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
    )

}

appengine {

    deploy {   // deploy configuration
        stopPreviousVersion = true  // default - stop the current version
        promote = true              // default - & make this the current version
    }

}

group = 'com.example'   // Generated output GroupId
version = '1.0-SNAPSHOT'          // Version in generated output

sourceCompatibility = 1.8
targetCompatibility = 1.8

HelloworldApplication.java:

package com.example.java.gettingstarted;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class HelloworldApplication {
  @RequestMapping("/service2/")
  public String home() {
    return "Helloooooooo Nurse!";
  }

  /**
   * (Optional) App Engine health check endpoint mapping.
   * @see <a href="https://cloud.google.com/appengine/docs/flexible/java/how-instances-are-managed#health_checking"></a>
   * If your app does not handle health checks, a HTTP 404 response is interpreted
   *     as a successful reply.
   */
  @RequestMapping("/_ah/health")
  public String healthy() {
    // Message body required though ignored
    return "Still surviving.";
  }

  public static void main(String[] args) {
    SpringApplication.run(HelloworldApplication.class, args);
  }
}

我也在运行 gcloud 版本 184.0.0

google-app-engine spring-boot app-engine-flexible
1个回答
4
投票

解决方案最终有点神奇,但是一旦 appengine 标准文档为我指明了正确的方向,SpringBoot 文档就告诉了我。

请注意,仅当您需要时才需要 WebApplicationInitializer 构建一个 war 文件并部署它。如果您更喜欢运行嵌入式 容器,那么你就根本不需要这个了。

我们正在部署一场战争,它在本地与嵌入式容器一起运行。按照提供的方式设置 jetty 并将神奇的 SpringBootServletInitializer 添加到根目录后,一切就开始工作了。我不知道为什么两周前不需要,但现在肯定需要。

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        System.out.println("ServletInitializer called.");
        return application.sources(HelloworldApplication.class);
    }
} 

将此文件放在根目录就可以了。

感谢您的帮助。

© www.soinside.com 2019 - 2024. All rights reserved.