Пружинная загрузка с sbt: невозможно запустить EmbeddedWebApplicationContext из-за отсутствия EmbeddedServletContainerFactory

Я упаковал свое весеннее загрузочное приложение, используя сборку sbt, и при попытке запустить 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 требует, чтобы в банке были вложенные банки (вместо Uber, который создается в сборке sbt). Итак, это дает мне два варианта. Упакуйте мой jar как вложенный jar с помощью sbt или настройте spring для использования обычного загрузчика классов и загрузки из Uber jar.

Я изучил вложенные плагины jar sbt и не могу найти ничего, что поддерживается (или даже в maven central). Это и то, и другое устарели годами, а не в Maven Central. У кого-нибудь есть предложения по этому поводу?

Я также изучил настройку весенней загрузки для использования jar-файлов uber, и подавляющим ответом является просто "использовать плагин maven", который здесь неприменим.

1 ответ

Вам необходимо предоставить встроенную фабрику контейнеров сервлетов в приложении. Это должно выглядеть примерно так:

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

Другие вопросы по тегам