带sbt的Spring引导:由于缺少EmbeddedServletContainerFactory,无法启动EmbeddedWebApplicationContext

带sbt的Spring引导:由于缺少EmbeddedServletContainerFactory,无法启动EmbeddedWebApplicationContext,spring,scala,spring-boot,sbt,sbt-assembly,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: Una

我已经使用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")
  )
)
我在周围做了一些挖掘,它看起来像(而不是像是用sbt组装创建的Uber jar)。所以,这给了我两个选择。使用sbt将我的jar打包为嵌套jar,或者将spring配置为使用普通类加载器并从Uber jar加载

我查看了嵌套的jar sbt插件,但似乎找不到任何维护的插件(甚至在maven central中)。这两个年份都过时了,而且不在maven central。有人对此有什么建议吗


我还研究了将spring boot配置为使用uber JAR,压倒性的回答是“使用maven插件”,这在这里不适用。

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