bloop
bloop copied to clipboard
Bloop `run --watch` doesn't appear to reload when Spring Boot "Spring-Fu" functional routing Netty app source changes
I have a Scala 3 app with the buildfile in SBT, using the above mentioned setup.
Doing bloop run <appname> --watch
doesn't appear to reload it on changes. Is there a trick to getting this to work 👀
https://user-images.githubusercontent.com/26604994/123532152-bb626580-d6d8-11eb-94e3-281a3516b5c2.mp4
package org.example
import scala.beans.BeanProperty
import reactor.core.publisher.Mono
import org.springframework.fu.jafu.Jafu.reactiveWebApplication
import org.springframework.fu.jafu.webflux.WebFluxServerDsl.webFlux
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import org.springframework.web.reactive.function.server.ServerResponse.ok
import org.springframework.fu.jafu.webflux.WebFluxServerDsl
case class Sample(@BeanProperty message: String)
class SampleService:
def generateMessage(): String = "Hello world!"
class SampleHandler(private var sampleService: SampleService):
def hello(request: ServerRequest): Mono[ServerResponse] =
ServerResponse.ok().bodyValue(sampleService.generateMessage())
def json(request: ServerRequest): Mono[ServerResponse] =
ServerResponse.ok().bodyValue(new Sample(sampleService.generateMessage()))
object Application {
val app = reactiveWebApplication((a) =>
a.beans((b) => b.bean(classOf[SampleHandler]).bean(classOf[SampleService]))
.enable(
webFlux((server) =>
server
.port(if (server.profiles().contains("test")) 8181 else 8080)
.router((app) => {
val handler = server.ref(classOf[SampleHandler])
app.GET("/", handler.hello)
app.GET("/api", handler.json)
})
.codecs(_.string().jackson())
)
)
)
def main(args: Array[String]): Unit = app.run(args)
}
ThisBuild / organization := "com.example"
ThisBuild / version := "0.0.1-SNAPSHOT"
ThisBuild / scalaVersion := "3.0.0"
val SPRING_VERSION = "2.6.0-SNAPSHOT"
lazy val root = (project in file("."))
.settings(
name := "demo",
resolvers ++= List(
"Spring Milestones" at "https://repo.spring.io/milestone",
"Spring Snapshots" at "https://repo.spring.io/snapshot"
),
libraryDependencies ++= List(
"org.springframework.boot" % "spring-boot-starter-parent" % SPRING_VERSION pomOnly (),
"org.springframework.boot" % "spring-boot-starter-actuator" % SPRING_VERSION,
"org.springframework.boot" % "spring-boot-starter-webflux" % SPRING_VERSION,
"org.springframework.fu" % "spring-fu-jafu" % "0.4.5-SNAPSHOT",
"org.springframework.boot" % "spring-boot-starter-test" % SPRING_VERSION % Test,
"io.projectreactor" % "reactor-test" % "3.4.7" % Test
)
)
bloopMainClass in (Compile, run) := Some("org.example.Application")
lazy val props = new {
val javaVersion = "16"
}
lazy val libs = new {}
Thanks for reporting! Did this work with an equivalent project in Scala 2? Or is it an overall global issue? Not sure yet what might be exactly a reason, but will take a look at it at some point.
I haven't yet tried it with Scala 2 (just started looking into Scala in general a few days ago, so still getting acquainted with the ecosystem/tooling).
Not sure yet what might be exactly a reason, but will take a look at it at some point.
Does bloop
wait for a process to finish before reloading?
It could be that. After I searched more on this, I found that the below two solutions both worked:
# With watchexec binary: https://github.com/watchexec/watchexec
$ watchexec --exts "scala" --watch ./src/main/scala --restart -- bloop run root
# With sbt-revolver plugin: https://github.com/spray/sbt-revolver
$ sbt ~reStart
The trick with watchexec
and it's cousin entr
http://eradman.com/entrproject/ are that they have a flag -r
/--reload
for long-running processes like webservers where they first stop/kill the current PID before restarting it again. I think this is how the sbt-revolver
plugin works as well, but I didn't look too much into it.
--watch
should work here from what I understand, but I might know the full story here.
I tried --watch
a couple times with bloop and it never stops the application. The app neeeds to quit on its own, only then will the file watching trigger a re-run.
This, in general, could be improved but seems like a bigger project :) e.g. the semantics of how you kill the previous instances would have to be defined (sigint, then sigkill after a timeout?)
I tried
--watch
a couple times with bloop and it never stops the application. The app neeeds to quit on its own, only then will the file watching trigger a re-run.This, in general, could be improved but seems like a bigger project :) e.g. the semantics of how you kill the previous instances would have to be defined (sigint, then sigkill after a timeout?)
Ach, yeah you are right! Something like hot swapping would most likely be useful here, but I haven't yet got back to that PR
I believe this boils down to a duplicate of #558