Jetty无法灵活地启动弹簧启动应用程序

时间:2018-01-16 21:20:25

标签: google-app-engine spring-boot app-engine-flexible

注意:这是一篇交叉帖子,因为我不确定这是技术问题还是错误,因此可以找到错误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

的build.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

1 个答案:

答案 0 :(得分:3)

解决方案最终变得有点神奇了,但是SpringBoot documentation告诉我,一旦标准文档向我指出正确的方向。

  

请注意,只有您需要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);
    }
} 

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

感谢您的帮助。