为什么我的 Ktor 应用程序会在几秒钟后失败?
Why does my Ktor app fail after few seconds?
我有一个小的 Ktor 应用程序(我知道这是一个愚蠢的应用程序,我是一个试图学习 Ktor 的初学者):
import com.auth0.jwt.JWT
import com.auth0.jwt.JWTVerifier
import com.auth0.jwt.algorithms.Algorithm
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.auth.jwt.*
import io.ktor.features.*
import io.ktor.jackson.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.netty.*
private val algorithm = Algorithm.HMAC256("secret")
private fun makeJwtVerifier(issuer: String, audience: String): JWTVerifier = JWT
.require(algorithm)
.withAudience(audience)
.withIssuer(issuer)
.build()
fun main(args: Array<String>): Unit = EngineMain.main(args)
fun Application.module(testing: Boolean = false) {
val jwtIssuer = environment.config.property("jwt.domain").getString()
val jwtAudience = environment.config.property("jwt.audience").getString()
val jwtRealm = environment.config.property("jwt.realm").getString()
install(ContentNegotiation) {
jackson()
}
install(Authentication) {
basic {
realm = jwtRealm
validate { credentials ->
UserIdPrincipal(credentials.name)
}
}
jwt {
realm = jwtRealm
verifier(makeJwtVerifier(jwtIssuer, jwtAudience))
validate { credential ->
if (credential.payload.audience.contains(jwtAudience)) JWTPrincipal(credential.payload) else null
}
}
}
routing {
authenticate("basic") {
post("/auth/login") {
val principal = call.principal<UserIdPrincipal>() ?: error ("no auth found")
call.respondText(principal.name)
}
}
}
}
和application.conf:
ktor {
development = true
deployment {
port = 8080
watch = [ com.contedevel ]
}
application {
modules = [ com.contedevel.backend.ApplicationKt.module ]
}
jwt {
domain = "https://localhost/"
audience = "jwt-audience"
realm = "acupoftea"
}
}
我的build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
application
kotlin("jvm") version "1.4.30"
}
group = "com.contedevel"
version = "1.0-SNAPSHOT"
application {
mainClass.set("io.ktor.server.netty.EngineMain")
}
repositories {
mavenCentral()
}
dependencies {
// Standard
implementation(kotlin("stdlib"))
// Ktor
implementation("io.ktor:ktor-server-core:1.5.2")
implementation("io.ktor:ktor-server-netty:1.5.2")
implementation("ch.qos.logback:logback-classic:1.2.1")
// Jackson
implementation("io.ktor:ktor-jackson:1.5.2")
// JWT
implementation("io.ktor:ktor-auth:1.5.2")
implementation("io.ktor:ktor-auth-jwt:1.5.2")
// Testing
testImplementation(kotlin("test-junit"))
}
tasks.test {
useJUnit()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
然后我尝试通过 ./gradlew run
启动应用程序,它显示了一些警告但失败了:
01:53:18.381 [Thread-0] DEBUG io.netty.util.internal.NativeLibraryLoader - netty_transport_native_kqueue cannot be loaded from java.library.path, now trying export to -Dio.netty.native.workdir: /var/folders/d5/x8gp_xv95xb0l5y3_gq_m1840000gn/T
java.lang.UnsatisfiedLinkError: no netty_transport_native_kqueue in java.library.path: /Users/denis/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2447)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:809)
at java.base/java.lang.System.loadLibrary(System.java:1893)
at io.netty.util.internal.NativeLibraryUtil.loadLibrary(NativeLibraryUtil.java:38)
at io.netty.util.internal.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:351)
at io.netty.util.internal.NativeLibraryLoader.load(NativeLibraryLoader.java:136)
at io.netty.channel.kqueue.Native.loadNativeLibrary(Native.java:128)
at io.netty.channel.kqueue.Native.<clinit>(Native.java:60)
at io.netty.channel.kqueue.KQueue.<clinit>(KQueue.java:37)
at io.ktor.server.netty.EventLoopGroupProxy$Companion.create(NettyApplicationEngine.kt:232)
at io.ktor.server.netty.NettyApplicationEngine$workerEventGroup.invoke(NettyApplicationEngine.kt:98)
at io.ktor.server.netty.NettyApplicationEngine$workerEventGroup.invoke(NettyApplicationEngine.kt:28)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at io.ktor.server.netty.NettyApplicationEngine.getWorkerEventGroup(NettyApplicationEngine.kt)
at io.ktor.server.netty.NettyApplicationEngine.access$getWorkerEventGroup$p(NettyApplicationEngine.kt:28)
at io.ktor.server.netty.NettyApplicationEngine$engineDispatcherWithShutdown.invoke(NettyApplicationEngine.kt:118)
at io.ktor.server.netty.NettyApplicationEngine$engineDispatcherWithShutdown.invoke(NettyApplicationEngine.kt:28)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at io.ktor.server.netty.NettyApplicationEngine.getEngineDispatcherWithShutdown(NettyApplicationEngine.kt)
at io.ktor.server.netty.NettyApplicationEngine.stop(NettyApplicationEngine.kt:181)
at io.ktor.server.engine.ApplicationEngineJvmKt.stop(ApplicationEngineJvm.kt:18)
at io.ktor.server.netty.EngineMain$main.invoke(EngineMain.kt:24)
at io.ktor.server.netty.EngineMain$main.invoke(EngineMain.kt:14)
at io.ktor.server.engine.ShutdownHook.run(ShutdownHook.kt:37)
Suppressed: java.lang.UnsatisfiedLinkError: no netty_transport_native_kqueue in java.library.path: /Users/denis/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2447)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:809)
at java.base/java.lang.System.loadLibrary(System.java:1893)
at io.netty.util.internal.NativeLibraryUtil.loadLibrary(NativeLibraryUtil.java:38)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at io.netty.util.internal.NativeLibraryLoader.run(NativeLibraryLoader.java:385)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312)
at io.netty.util.internal.NativeLibraryLoader.loadLibraryByHelper(NativeLibraryLoader.java:377)
at io.netty.util.internal.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:341)
... 19 common frames omitted
01:53:18.394 [Thread-0] DEBUG io.netty.channel.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 24
01:53:18.401 [Thread-0] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.initialSize: 1024
01:53:18.401 [Thread-0] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.maxSize: 4096
01:53:18.404 [Thread-0] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
01:53:18.404 [Thread-0] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
01:53:18.408 [Thread-0] DEBUG io.netty.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
> Task :run FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':run'.
> Process 'command '/Library/Java/JavaVirtualMachines/liberica-jdk-15-full.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 8s
但是,当我调用 ./gradlew build
时,一切都成功了...我的错误是什么?
P.S. 我用 Liberica JDK v.15.
我在 运行 你的应用程序时遇到两个错误:
Property jwt.audience not found
。这个错误和类似的错误可以通过传递所需的参数来修复:./gradlew run -P:jwt.domain=domain -P:jwt.audience=audience -P:jwt.realm=realm
Provider with the name null is already registered
。这是由于未命名提供程序的名称冲突造成的,可以通过显式命名来解决:
修改后的代码如下:
install(Authentication) {
basic("basic") {
realm = jwtRealm
validate { credentials ->
UserIdPrincipal(credentials.name)
}
}
jwt("jwt") {
realm = jwtRealm
verifier(makeJwtVerifier(jwtIssuer, jwtAudience))
validate { credential ->
if (credential.payload.audience.contains(jwtAudience)) JWTPrincipal(credential.payload) else null
}
}
}
我有一个小的 Ktor 应用程序(我知道这是一个愚蠢的应用程序,我是一个试图学习 Ktor 的初学者):
import com.auth0.jwt.JWT
import com.auth0.jwt.JWTVerifier
import com.auth0.jwt.algorithms.Algorithm
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.auth.jwt.*
import io.ktor.features.*
import io.ktor.jackson.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.netty.*
private val algorithm = Algorithm.HMAC256("secret")
private fun makeJwtVerifier(issuer: String, audience: String): JWTVerifier = JWT
.require(algorithm)
.withAudience(audience)
.withIssuer(issuer)
.build()
fun main(args: Array<String>): Unit = EngineMain.main(args)
fun Application.module(testing: Boolean = false) {
val jwtIssuer = environment.config.property("jwt.domain").getString()
val jwtAudience = environment.config.property("jwt.audience").getString()
val jwtRealm = environment.config.property("jwt.realm").getString()
install(ContentNegotiation) {
jackson()
}
install(Authentication) {
basic {
realm = jwtRealm
validate { credentials ->
UserIdPrincipal(credentials.name)
}
}
jwt {
realm = jwtRealm
verifier(makeJwtVerifier(jwtIssuer, jwtAudience))
validate { credential ->
if (credential.payload.audience.contains(jwtAudience)) JWTPrincipal(credential.payload) else null
}
}
}
routing {
authenticate("basic") {
post("/auth/login") {
val principal = call.principal<UserIdPrincipal>() ?: error ("no auth found")
call.respondText(principal.name)
}
}
}
}
和application.conf:
ktor {
development = true
deployment {
port = 8080
watch = [ com.contedevel ]
}
application {
modules = [ com.contedevel.backend.ApplicationKt.module ]
}
jwt {
domain = "https://localhost/"
audience = "jwt-audience"
realm = "acupoftea"
}
}
我的build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
application
kotlin("jvm") version "1.4.30"
}
group = "com.contedevel"
version = "1.0-SNAPSHOT"
application {
mainClass.set("io.ktor.server.netty.EngineMain")
}
repositories {
mavenCentral()
}
dependencies {
// Standard
implementation(kotlin("stdlib"))
// Ktor
implementation("io.ktor:ktor-server-core:1.5.2")
implementation("io.ktor:ktor-server-netty:1.5.2")
implementation("ch.qos.logback:logback-classic:1.2.1")
// Jackson
implementation("io.ktor:ktor-jackson:1.5.2")
// JWT
implementation("io.ktor:ktor-auth:1.5.2")
implementation("io.ktor:ktor-auth-jwt:1.5.2")
// Testing
testImplementation(kotlin("test-junit"))
}
tasks.test {
useJUnit()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
然后我尝试通过 ./gradlew run
启动应用程序,它显示了一些警告但失败了:
01:53:18.381 [Thread-0] DEBUG io.netty.util.internal.NativeLibraryLoader - netty_transport_native_kqueue cannot be loaded from java.library.path, now trying export to -Dio.netty.native.workdir: /var/folders/d5/x8gp_xv95xb0l5y3_gq_m1840000gn/T
java.lang.UnsatisfiedLinkError: no netty_transport_native_kqueue in java.library.path: /Users/denis/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2447)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:809)
at java.base/java.lang.System.loadLibrary(System.java:1893)
at io.netty.util.internal.NativeLibraryUtil.loadLibrary(NativeLibraryUtil.java:38)
at io.netty.util.internal.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:351)
at io.netty.util.internal.NativeLibraryLoader.load(NativeLibraryLoader.java:136)
at io.netty.channel.kqueue.Native.loadNativeLibrary(Native.java:128)
at io.netty.channel.kqueue.Native.<clinit>(Native.java:60)
at io.netty.channel.kqueue.KQueue.<clinit>(KQueue.java:37)
at io.ktor.server.netty.EventLoopGroupProxy$Companion.create(NettyApplicationEngine.kt:232)
at io.ktor.server.netty.NettyApplicationEngine$workerEventGroup.invoke(NettyApplicationEngine.kt:98)
at io.ktor.server.netty.NettyApplicationEngine$workerEventGroup.invoke(NettyApplicationEngine.kt:28)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at io.ktor.server.netty.NettyApplicationEngine.getWorkerEventGroup(NettyApplicationEngine.kt)
at io.ktor.server.netty.NettyApplicationEngine.access$getWorkerEventGroup$p(NettyApplicationEngine.kt:28)
at io.ktor.server.netty.NettyApplicationEngine$engineDispatcherWithShutdown.invoke(NettyApplicationEngine.kt:118)
at io.ktor.server.netty.NettyApplicationEngine$engineDispatcherWithShutdown.invoke(NettyApplicationEngine.kt:28)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at io.ktor.server.netty.NettyApplicationEngine.getEngineDispatcherWithShutdown(NettyApplicationEngine.kt)
at io.ktor.server.netty.NettyApplicationEngine.stop(NettyApplicationEngine.kt:181)
at io.ktor.server.engine.ApplicationEngineJvmKt.stop(ApplicationEngineJvm.kt:18)
at io.ktor.server.netty.EngineMain$main.invoke(EngineMain.kt:24)
at io.ktor.server.netty.EngineMain$main.invoke(EngineMain.kt:14)
at io.ktor.server.engine.ShutdownHook.run(ShutdownHook.kt:37)
Suppressed: java.lang.UnsatisfiedLinkError: no netty_transport_native_kqueue in java.library.path: /Users/denis/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2447)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:809)
at java.base/java.lang.System.loadLibrary(System.java:1893)
at io.netty.util.internal.NativeLibraryUtil.loadLibrary(NativeLibraryUtil.java:38)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at io.netty.util.internal.NativeLibraryLoader.run(NativeLibraryLoader.java:385)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312)
at io.netty.util.internal.NativeLibraryLoader.loadLibraryByHelper(NativeLibraryLoader.java:377)
at io.netty.util.internal.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:341)
... 19 common frames omitted
01:53:18.394 [Thread-0] DEBUG io.netty.channel.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 24
01:53:18.401 [Thread-0] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.initialSize: 1024
01:53:18.401 [Thread-0] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.maxSize: 4096
01:53:18.404 [Thread-0] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
01:53:18.404 [Thread-0] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
01:53:18.408 [Thread-0] DEBUG io.netty.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
> Task :run FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':run'.
> Process 'command '/Library/Java/JavaVirtualMachines/liberica-jdk-15-full.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 8s
但是,当我调用 ./gradlew build
时,一切都成功了...我的错误是什么?
P.S. 我用 Liberica JDK v.15.
我在 运行 你的应用程序时遇到两个错误:
Property jwt.audience not found
。这个错误和类似的错误可以通过传递所需的参数来修复:./gradlew run -P:jwt.domain=domain -P:jwt.audience=audience -P:jwt.realm=realm
Provider with the name null is already registered
。这是由于未命名提供程序的名称冲突造成的,可以通过显式命名来解决:
修改后的代码如下:
install(Authentication) {
basic("basic") {
realm = jwtRealm
validate { credentials ->
UserIdPrincipal(credentials.name)
}
}
jwt("jwt") {
realm = jwtRealm
verifier(makeJwtVerifier(jwtIssuer, jwtAudience))
validate { credential ->
if (credential.payload.audience.contains(jwtAudience)) JWTPrincipal(credential.payload) else null
}
}
}