Reputation: 678
I'm using Ktor for my back end, I am planning to use auto reload and when I used engine main I've configured development mode in application.conf file. How to do the same in embedded server?
fun main() {
embeddedServer(Netty, port = 8080 ,watchPaths = listOf("classes","resources")) {
module()
}.start(wait = true)
}
Upvotes: 9
Views: 5379
Reputation: 1444
If you want to auto-reload the backend classes/resources, you can launch Ktor from your IDE like this:
fun main() {
System.setProperty("io.ktor.development", "true")
embeddedServer(
Netty,
port = 8080,
host = "127.0.0.1",
watchPaths = listOf(
"classes",
"resources"
)
) {
// ...
}.start(wait = true)
}
Then from the command line you can run ./gradlew -t :<backend-module>:classes
.
However, if you want to auto-reload the frontend in a full stack application, your main methods can be:
fun main() {
System.setProperty("io.ktor.development", "true")
val jsFile = Path.of(".").resolve("<frontend-module/build/distributions/frontend-module.js>").toFile()
embeddedServer(
Netty,
port = 8080,
host = "127.0.0.1"
) {
routing {
get("/static/frontend-module.js") {
call.respondFile(jsFile)
}
}
// ...
}.start(wait = true)
}
Then add the following in the frontend module build.gradle.kts:
val devMode = properties.containsKey("jsWatch")
kotlin {
js {
useCommonJs()
binaries.executable()
browser {
val webpackMode =
if (devMode) { Mode.DEVELOPMENT }
else { Mode.PRODUCTION }
commonWebpackConfig {
mode = webpackMode
}
}
}
}
Then add a file inside the <frontend-module>/webpack.config.d
folder, for example called watch.js:
const productionMode = config.mode === "production";
config.watch = ! productionMode;
Then after running the above frontend auto-reload main function from the IDE, you can run the following from the command line: ./gradlew -t :sample-ktor-react-js:build -x test -PjsWatch
Here's a working example: https://github.com/alexoooo/sample-ktor-react
Upvotes: 4
Reputation: 883
For me it worked with this code in application.conf
ktor {
development = true
deployment {
port = 8080
port = ${?PORT}
}
application {
modules = [ com.myapp.ApplicationKt.module ]
}
}
jwt {
domain = "https://jwt-provider-domain/"
audience = "jwt-audience"
realm = "ktor sample app"
}
and this is how i checked it
fun Application.module() {
println("developmentMode: " +this.environment.developmentMode)
...
Upvotes: 1
Reputation: 594
In intellijIdea, go to Run COnfiguration, add this to VM Options -Dio.ktor.development=false
Upvotes: 1
Reputation: 11
fun main() {
embeddedServer(
Netty, port = 80, host = "0.0.0.0", developmentMode = true, watchPaths = listOf("main")
) {
configureRouting()
configureSerialization()
}.start(wait = true)
}
@OptIn(DelicateCoroutinesApi::class)
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> embeddedServer(
factory: ApplicationEngineFactory<TEngine, TConfiguration>,
port: Int = 80,
host: String = "0.0.0.0",
developmentMode: Boolean = false,
watchPaths: List<String> = listOf(File(".").canonicalPath),
configure: TConfiguration.() -> Unit = {},
module: Application.() -> Unit
): TEngine = GlobalScope.embeddedServer(
factory, port, host, developmentMode, watchPaths, EmptyCoroutineContext, configure, module
)
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> CoroutineScope.embeddedServer(
factory: ApplicationEngineFactory<TEngine, TConfiguration>,
port: Int = 80,
host: String = "0.0.0.0",
developmentMode: Boolean = false,
watchPaths: List<String> = listOf(File(".").canonicalPath),
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext,
configure: TConfiguration.() -> Unit = {},
module: Application.() -> Unit
): TEngine {
val connectors: Array<EngineConnectorConfig> = arrayOf(EngineConnectorBuilder().apply {
this.port = port
this.host = host
})
val environment = applicationEngineEnvironment {
this.parentCoroutineContext = coroutineContext + parentCoroutineContext
this.log = KtorSimpleLogger("ktor.application")
this.watchPaths = watchPaths
this.module(module)
this.connectors.addAll(connectors)
this.developmentMode = developmentMode
}
return embeddedServer(factory, environment, configure)
}
What I tried and worked is created my own functions to created an embededServer. basically I copied EmbeddedServer.kt logic and exposed developmentMode. If you are using Intellij you need to press the Build button to work, or enable auto build. However i dont think is a good idea because you need a way to update this value for other environments. Thus it should be done by application.conf or from applicationDefaultJvmArgs in gradle.
Edit: Went back and tried latest version for ktor. You can use something like this. Also make sure you have enable auto build or you will have to build each time while server is running.
fun main() {
embeddedServer(
Netty,
environment = applicationEngineEnvironment {
log = LoggerFactory.getLogger("ktor.application")
config = HoconApplicationConfig(ConfigFactory.load())
developmentMode = true
watchPaths = listOf("class")
connector {
port = 8080
host = "localhost"
}
module {
defaultModule()
}
}
).start(wait = true)
}
Upvotes: 1