【问题标题】:Spring boot with sbt: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory使用 sbt 进行 Spring 启动:由于缺少 EmbeddedServletContainerFactory,无法启动 EmbeddedWebApplicationContext
【发布时间】:2017-03-30 01:28:52
【问题描述】:

我已经使用 sbt 程序集打包了我的 Spring Boot 应用程序,并且在尝试运行我收到的 jar 时

Application startup failed
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is 
    org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.

该项目在 Intellij 中运行良好。我的 build.sbt 在下面

lazy val news = (project in file("wherever")).
enablePlugins(DockerPlugin).
settings(commonSettings: _*).
settings(
  name := "name",
  mainClass in assembly := Some("mainEntry"),
  test in assembly := {},
  assemblyJarName := "jarName",
  libraryDependencies ++= dependency1,
  libraryDependencies ++= dependency2,
  libraryDependencies += ScalaTest,
  scalaSource in Compile := baseDirectory.value / "src/main/scala",
  dockerfile in docker := {
    val artifact: File = assembly.value
    val artifactTargetPath = "/"
    new Dockerfile {
      from("openjdk:8-jre-alpine")
      add(artifact, artifactTargetPath)
      add(new File("./config/"),"/config")
      cmd("java", "-jar", " -Denv=$env","jarName")
      env("env","stage")
    }
  },
  imageNames in docker := Seq(
    ImageName("imageName")
  )
)

我已经进行了一些挖掘,它看起来像Spring Boot requires the jar to contain nested jars(而不是像使用 sbt 程序集创建的 Uber jar)。所以,这给了我两个选择。使用 sbt 将我的 jar 打包为嵌套 jar,或者配置 spring 以使用普通的类加载器并从 Uber jar 加载。

我查看了嵌套的 jar sbt 插件,但似乎找不到任何维护的东西(甚至在 maven Central 中)。 Thisthis 都已过时且不在 Maven 中心。有没有人对此有任何建议?

我还研究了配置 spring boot 以使用 uber jars,压倒性的反应只是“使用 maven 插件”,这在此处不适用。

【问题讨论】:

    标签: spring scala spring-boot sbt sbt-assembly


    【解决方案1】:

    您需要在应用程序上提供嵌入式 servlet 容器工厂。它应该如下所示:

    import org.springframework.boot.SpringApplication
    import org.springframework.boot.autoconfigure.SpringBootApplication
    import org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration
    import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory
    import org.springframework.boot.context.web.SpringBootServletInitializer
    import org.springframework.context.annotation.{Bean, ComponentScan, Configuration, PropertySource}
    
    /**
     * Spring boot application configuration and servlet initializer.
     */
    @Configuration
    @ComponentScan(value = Array("com.foobusiness.foopackage"))
    @PropertySource(Array("classpath:application.properties"))
    @SpringBootApplication(exclude = Array(classOf[ErrorMvcAutoConfiguration]))
    class Application extends SpringBootServletInitializer {
      @Bean
      def servletContainer: JettyEmbeddedServletContainerFactory = new JettyEmbeddedServletContainerFactory()
    }
    
    object Application {
      def main(args: Array[String]): Unit = {
        SpringApplication run classOf[Application]
      }
    }
    

    显然,上面使用了 Jetty,这意味着您还需要包含 jetty-runner 作为库编译时依赖项。你的sbt构建文件在编译、运行或者打包的时候也需要用到上面的类:

    mainClass in(Compile, run, packageBin) := Some("com.foobusiness.foopackage.Application"),
    

    应用程序可以使用sbt run从命令行运行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-19
      • 2016-03-05
      • 2014-07-28
      • 2016-05-06
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 2016-10-22
      相关资源
      最近更新 更多