Closed earldouglas closed 1 month ago
I'm trying to build a Spring Boot WAR for JBoss via the ContainerPlugin, without luck.
Is it not working because xsbt-web-plugin doesn't support Undertow yet? It looks like tomcat-embed-*.jar
is added to the manifest regardless of what I put in Container / containerLibs
.
Thanks for the info; that helps point me in the right direction. I will put something together for this later today.
Can you give TomcatPlugin
a try, rather than ContainerPlugin
? I can get a minimal Spring Boot project working with it:
Step 1: Start a new Spring Boot project Step 2: Add your code
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.2")
TomcatPlugin
libraryDependencies ++=
Seq(
"org.springframework.boot" % "spring-boot-starter-web" % "2.5.1",
"org.springframework.boot" % "spring-boot-starter-tomcat" % "2.5.1" % "provided",
"org.springframework.boot" % "spring-boot-starter-test" % "2.5.1" % "test",
)
enablePlugins(TomcatPlugin)
$ sbt
> tomcat:start
$ curl localhost:8080/hello
Hello World!
Wow, thanks for the fast reply!
I followed your steps and created a minimal reproducer here: https://github.com/AugustNagro/springboot-mvp
Running with run
works, but Tomcat / start
does not. The log is:
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Jun 20, 2021 7:24:40 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service [Tomcat]
Jun 20, 2021 7:24:40 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet engine: [Apache Tomcat/9.0.38]
Jun 20, 2021 7:24:40 PM org.apache.catalina.startup.ContextConfig getDefaultWebXmlFragment
INFO: No global web.xml found
Jun 20, 2021 7:24:42 PM org.apache.jasper.servlet.TldScanner scanJars
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Jun 20, 2021 7:24:42 PM org.apache.catalina.core.ApplicationContext log
INFO: 1 Spring WebApplicationInitializers detected on classpath
Jun 20, 2021 7:24:42 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
I don't know much about Spring Boot, but based on the example project from https://start.spring.io/, I think you need to add one additional class:
src/main/scala/com/example/mvp/ServletInitializer.scala:
package com.example.mvp
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
class ServletInitializer extends SpringBootServletInitializer:
override def configure(application: SpringApplicationBuilder): SpringApplicationBuilder =
application.sources(classOf[SpringMVP])
Then run tomcat:start
, and you should see a bunch of Spring-related output, as well as a working endpoint:
$ curl localhost:8080
Gus
Awesome, tomcat:start
is working!
But when running on JBoss, I get
java.lang.ClassCastException: org.apache.tomcat.websocket.server.WsServerContainer cannot be cast to io.undertow.websockets.jsr.ServerWebSocketContainer​
I've tried excluding the Tomcat WS dependency as per stack overflow, but no dice so far.
excludeDependencies ++= Seq(
// https://stackoverflow.com/questions/25792121/spring-boot-websockets-in-wildfly?answertab=votes#tab-top
"org.apache.tomcat.embed" % "tomcat-embed-websocket"
)
Ok, got it working in JBoss!
Just switched to the ContainerPlugin.
It looks like spring-boot-starter-web
is pulling in spring-boot-starter-tomcat
as a transitive dependency, which conflicts with JBoss's own libraries. You can exclude it from being included by adding an exclude()
to the libraryDependencies
line:
libraryDependencies ++= Seq(
"org.springframework.boot" % "spring-boot-starter-web" % SpringBootVersion exclude("org.springframework.boot", "spring-boot-starter-tomcat"),
Just switched to the ContainerPlugin.
Note that this has no effect on the .war file produced by package
, and will prevent you from being able to launch Tomcat via tomcat:start
.
Sweet, that's a better solution.
https://undertow.io/undertow-docs/undertow-docs-2.0.0/#creating-a-servlet-deployment