Пружинная загрузка с 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