使用sbt进行Spring启动:由于缺少EmbeddedServletContainerFactory,无法启动EmbeddedWebApplicationContext

时间:2016-11-16 00:31:29

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

我已经使用sbt程序集打包我的spring启动应用程序,并且在尝试运行我收到的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)。所以,这给了我两个选择。将我的jar打包为带有sbt的嵌套jar或配置spring以使用普通的类加载器并从Uber jar加载。

我已经研究过嵌套的jar sbt插件,我似乎无法找到任何维护的东西(甚至在maven中心)。 Thisthis都已过时,而不是maven中心。有没有人对此有任何建议?

我也考虑过配置spring boot来使用uber jar,而压倒性的响应只是“使用maven插件”,这里不适用。

1 个答案:

答案 0 :(得分:0)

您需要在应用程序上提供嵌入式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

从命令行运行应用程序