Hi. I run a Ktor server on Android 5+, and I'm try...
# ktor
g
Hi. I run a Ktor server on Android 5+, and I'm trying to upgrade Ktor from 1.4 to 1.6. Unfortunately, some of the changes in ktor uses
java.nio.file.FileSystems
, which breaks on Android 5-8 but works in newer versions. This line in `ApplicationEngineEnvironmentReloading` is the culprit, but I don't think that class should be used in production, right? So how can I disable that behaviour, so that that class won't be loaded? I'm not running the server in development mode, so it shouldn't be trying to reload the server.
👀 1
I just reported this bug, but if anyone can think of a workaround I'd really appreciate it.
a
As a workaround, you can explicitly pass empty list for watch paths:
Copy code
val server = embeddedServer(CIO, port = 8082, watchPaths = emptyList()) {
    routing {
        get("/") {}
    }
}
g
Thanks! I'll try it now. But I just realised autoreload isn't used anyway according to the logs (which I've just enabled):
INFO ktor.application - Autoreload is disabled because the development mode is off.
So that code using
java.nio.file.FileSystems
must be executed anyway regardless of development mode
a
That's why I suggested passing an empty list for watch paths. There are guards like
watchPatterns.isEmpty()
before usage of
watcher
.
g
Oh cool. I'm going to try it in a moment and I'll let you know how it goes.
I get a different error on Android 5-7 if I make the change you suggested:
Copy code
java.lang.NoSuchMethodError: No virtual method getParameterCount()I in class Ljava/lang/reflect/Constructor; or its super classes (declaration of 'java.lang.reflect.Constructor' appears in /system/framework/core-libart.jar)

     FATAL EXCEPTION: main
Process: tech.relaycorp.gateway, PID: 6740
java.lang.NoSuchMethodError: No virtual method getParameterCount()I in class Ljava/lang/reflect/Constructor; or its super classes (declaration of 'java.lang.reflect.Constructor' appears in /system/framework/core-libart.jar)
	at io.ktor.server.engine.internal.CallableUtilsKt.executeModuleFunction(CallableUtils.kt:43)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$launchModuleByName$1.invoke(ApplicationEngineEnvironmentReloading.kt:317)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$launchModuleByName$1.invoke(ApplicationEngineEnvironmentReloading.kt:316)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartupFor(ApplicationEngineEnvironmentReloading.kt:341)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.launchModuleByName(ApplicationEngineEnvironmentReloading.kt:316)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$launchModuleByName(ApplicationEngineEnvironmentReloading.kt:30)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:304)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:295)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartup(ApplicationEngineEnvironmentReloading.kt:323)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.instantiateAndConfigureApplication(ApplicationEngineEnvironmentReloading.kt:295)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createApplication(ApplicationEngineEnvironmentReloading.kt:136)
	at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.start(ApplicationEngineEnvironmentReloading.kt:268)
	at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:174)
	at tech.relaycorp.gateway.pdc.local.PDCServer$start$2.invokeSuspend(PDCServer.kt:41)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
The server continues to work on Android 8+.
a
That's something in the code of a module most likely not related to Ktor.
g
I've just created a minimal app from scratch and I get the same behaviour when I try to upgrade to ktor 1.6.
Also, unless I'm misreading it, the stack trace suggests the exception is thrown at
io.ktor.server.engine.internal.CallableUtilsKt.executeModuleFunction(CallableUtils.kt:43)
a
Sorry, I misread the stack trace. Indeed, the
getParameterCount
method was added in Android API 26.
👍 1
Here is the issue.
g
Thanks!