使用 Spring boot + gradle、Jetty 错误部署 AppEngine Flexible

Deploy AppEngine Flexible using Spring boot + gradle, Jetty Error

我有一个 Google App Engine Flexible 使用 gradle 和 spring 启动的应用程序。我的 build.gradle 文件如下:

buildscript {
repositories {
    mavenCentral()
}
dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.5.RELEASE")
    classpath 'io.spring.gradle:dependency-management-plugin:0.6.1.RELEASE'
    classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.5.RELEASE")
    classpath 'com.google.cloud.tools:appengine-gradle-plugin:+'    // latest App Engine Gradle tasks       
    }
}
    apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
apply plugin: 'com.google.cloud.tools.appengine'  // App Engine tasks
war {
    baseName = 'gs-accessing-mongodb-data-rest'
    version =  '0.1.0'
}
repositories {
    mavenCentral()
}
configurations {
    providedRuntime
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
    providedCompile group: 'javax.servlet', name: 'servlet-api', version:'2.5'
    compile 'com.google.appengine:appengine:+'
    compile("org.springframework.boot:spring-boot-starter-data-rest")
    compile("org.springframework.boot:spring-boot-starter-data-mongodb")    
    //compile("org.springframework.boot:spring-boot-starter-web")  
    compile("org.springframework:spring-webmvc:4.2.3.RELEASE")
    compile("org.springframework:spring-tx:4.2.3.RELEASE")  
    testCompile("org.springframework.boot:spring-boot-starter-test") 
    compile("javax.servlet:jstl:1.2")
    //compile("javax.servlet:javax.servlet-api:2.5")
    compile("javax.servlet:servlet-api:2.5")  
    compile("org.codehaus.jackson:jackson-mapper-asl:1.9.13")
    compile("com.fasterxml.jackson.core:jackson-databind:2.5.3")
    compile("com.fasterxml.jackson.core:jackson-core:2.5.3")
    compile("commons-fileupload:commons-fileupload:1.3.1")
    compile("commons-io:commons-io:2.4")
    testCompile("junit:junit")
    providedRuntime 'org.apache.tomcat.embed:tomcat-embed-jasper'
    compile 'org.mongodb:mongo-java-driver:3.2.2'    
}
appengine {  // App Engine tasks configuration
  deploy {   // deploy configuration
    stopPreviousVersion = true  // default - stop the current version
    promote = true              // default - & make this the current version
  }
}
group = 'com.acin.shelfcheck'   // Generated output GroupId
version = '1.0-SNAPSHOT'          // Version in generated output
eclipse {
    project.natures 'org.eclipse.buildship.core.gradleprojectnature'
}

当我尝试在 Google AppEngine Flexible 中部署我的应用程序时,出现以下错误:

    Application startup error:
        at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:561)
        at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:236)
        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.run(XmlConfiguration.java:1511)
        at org.eclipse.jetty.xml.XmlConfiguration.run(XmlConfiguration.java:1438)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1437)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.eclipse.jetty.start.Main.invokeMain(Main.java:220)
        at org.eclipse.jetty.start.Main.start(Main.java:484)
        at org.eclipse.jetty.start.Main.main(Main.java:77)
2017-04-03 11:50:03.416:INFO:root:main: 2 Spring WebApplicationInitializers detected on classpath
2017-04-03 11:50:03.681:WARN:oejd.DeploymentManager:main: Unable to reach node goal: started
java.util.ServiceConfigurationError: org.apache.juli.logging.Log: Provider org.eclipse.jetty.apache.jsp.JuliLog not a subtype
        at java.util.ServiceLoader.fail(ServiceLoader.java:239)
        at java.util.ServiceLoader.access0(ServiceLoader.java:185)
        at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376)
        at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
        at java.util.ServiceLoader.next(ServiceLoader.java:480)
        at org.apache.juli.logging.LogFactory.<init>(LogFactory.java:78)
        at org.apache.juli.logging.LogFactory.<clinit>(LogFactory.java:66)
        at org.apache.tomcat.websocket.server.WsServerContainer.<clinit>(WsServerContainer.java:76)
        at org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131)
        at org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:47)
        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:1480)
        at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1442)
        at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:788)
        at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:261)
        at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:540)
        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:499)
        at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:147)
        at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180)
        at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:452)
        at org.eclipse.jetty.deploy.providers.ScanningAppProvider.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:561)
        at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:236)
        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.run(XmlConfiguration.java:1511)
        at org.eclipse.jetty.xml.XmlConfiguration.run(XmlConfiguration.java:1438)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1437)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.eclipse.jetty.start.Main.invokeMain(Main.java:220)
        at org.eclipse.jetty.start.Main.start(Main.java:484)
        at org.eclipse.jetty.start.Main.main(Main.java:77)

    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.run(XmlConfiguration.java:1511)
        at org.eclipse.jetty.xml.XmlConfiguration.run(XmlConfiguration.java:1438)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1437)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.eclipse.jetty.start.Main.invokeMain(Main.java:220)
        at org.eclipse.jetty.start.Main.start(Main.java:484)
        at org.eclipse.jetty.start.Main.main(Main.java:77)
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.eclipse.jetty.start.Main.invokeMain(Main.java:220)
        at org.eclipse.jetty.start.Main.start(Main.java:484)
        at org.eclipse.jetty.start.Main.main(Main.java:77)
Caused by: 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.run(XmlConfiguration.java:1511)
        at org.eclipse.jetty.xml.XmlConfiguration.run(XmlConfiguration.java:1438)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1437)
        ... 7 more
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.eclipse.jetty.start.Main.invokeMain(Main.java:220)
        at org.eclipse.jetty.start.Main.start(Main.java:484)
        at org.eclipse.jetty.start.Main.main(Main.java:77)
Caused by: 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.run(XmlConfiguration.java:1511)
        at org.eclipse.jetty.xml.XmlConfiguration.run(XmlConfiguration.java:1438)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1437)
        ... 7 more

我的 gradle 文件哪里弄错了?

您的应用程序中设置了 2 个容器。

org.apache.tomcat.websocket.server.WsServerContainer

这在 Jetty 上是不可能的。

查找具有 class org.apache.tomcat.websocket.server.WsSci 的 jar 文件,您要么必须将其替换为非 Tomcat 特定的内容,要么将其删除。

正如 Joakim 所解释的删除 org.apache.tomcat.websocket.server.WsSci 我已经排除了 tomcat 因为它已在 link 中解释如下:

Maven 中的示例:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

Gradle中的示例:

    configurations {
compile.exclude module: "spring-boot-starter-tomcat"
}
dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:1.5.2.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-jetty:1.5.2.RELEASE")
    // ...
}

我遇到了同样的问题,解决方法如下。

  1. 创建 ServletInitializer.java(用于部署更改 jar -> war)

    • Spring Boot packaging the project to War
  2. 修改build.gradle

    • 添加依赖项 graprovidedRuntime('org.springframework.boot:spring-boot-starter-tomcat')

build.gradle

中的示例
buildscript {
    ext {
        springBootVersion = '2.0.3.RELEASE'
    }
    repositories {
        jcenter()
        mavenCentral()
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath 'com.google.cloud.tools:appengine-gradle-plugin:2.0.0-rc3'
    }
}

apply plugin: 'java'
apply plugin: 'war'  
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.google.cloud.tools.appengine'



repositories {
    mavenCentral()


}

group   = "yourProjectID"        // Generated output GroupId
version = "1.0-SNAPSHOT"       // Version in generated output

sourceCompatibility = 1.8
targetCompatibility = 1.8

appengine {
    deploy {
        version = "GCLOUD_CONFIG"
        projectId = "GCLOUD_CONFIG"
    }
}

dependencies {

    compile("org.springframework.boot:spring-boot-starter-web")

     ....

    providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
}