ktorio / ktor

Framework for quickly creating connected applications in Kotlin with minimal effort
https://ktor.io
Apache License 2.0
12.78k stars 1.04k forks source link

LinkageError: loader constraint violation #783

Closed Ccixyj closed 5 years ago

Ccixyj commented 5 years ago

Ktor Version

1.0.1

Ktor Engine Used(client or server and name)

server netty

JVM Version, Operating System and Relevant Context

jdk1.8.0_181 ,windows

Feedback

code based on ktor-samples/feature/testable:

add main function

fun Application.main() {
    install(CallLogging)
    routing {
        trace { log.info(it.buildText()) }
        get("/") {
            call.respondText("Hello from Ktor Testable sample application")
        }
    }
}

fun main(args: Array<String>) {
    embeddedServer(Netty,port = 8080, module = Application::main , watchPaths = listOf("/")).start()
}

request "localhost:8080" cause this error

remove watchPaths or trace { application.log.info(it.buildText()) } is ok

stacktrace:

java.lang.LinkageError: loader constraint violation: loader (instance of io/ktor/server/engine/OverridingClassLoader$ChildURLClassLoader) previously initiated loading for a different type with name "org/slf4j/Logger"
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at io.ktor.server.engine.OverridingClassLoader$ChildURLClassLoader.findClass(OverridingClassLoader.kt:39)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at io.ktor.samples.testable.TestableApplicationKt$main$1$1.invoke(TestableApplication.kt:21)
    at io.ktor.samples.testable.TestableApplicationKt$main$1$1.invoke(TestableApplication.kt)
    at io.ktor.routing.RoutingResolveContext.resolve(RoutingResolve.kt:78)
    at io.ktor.routing.Routing.interceptor(Routing.kt:27)
    at io.ktor.routing.Routing$Feature$install$1.invokeSuspend(Routing.kt:75)
    at io.ktor.routing.Routing$Feature$install$1.invoke(Routing.kt)
    at io.ktor.util.pipeline.PipelineContext.proceed(PipelineContext.kt:53)
    at io.ktor.features.CallLogging$Feature$install$2.invokeSuspend(CallLogging.kt:124)
    at io.ktor.features.CallLogging$Feature$install$2.invoke(CallLogging.kt)
    at io.ktor.util.pipeline.PipelineContext.proceed(PipelineContext.kt:53)
    at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:24)
    at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$2.invokeSuspend(DefaultEnginePipeline.kt:80)
    at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$2.invoke(DefaultEnginePipeline.kt)
    at io.ktor.util.pipeline.PipelineContext.proceed(PipelineContext.kt:53)
    at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:24)
    at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1.invokeSuspend(NettyApplicationCallHandler.kt:31)
    at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1.invoke(NettyApplicationCallHandler.kt)
    at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:54)
    at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:111)
    at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:160)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:54)
    at kotlinx.coroutines.BuildersKt.launch(Unknown Source)
    at io.ktor.server.netty.NettyApplicationCallHandler.handleRequest(NettyApplicationCallHandler.kt:22)
    at io.ktor.server.netty.NettyApplicationCallHandler.channelRead(NettyApplicationCallHandler.kt:16)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:38)
    at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:353)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)
cy6erGn0m commented 5 years ago

Could you please provide full stacktrace?

Ccixyj commented 5 years ago

Could you please provide full stacktrace?

I have edited ,check please.

cy6erGn0m commented 5 years ago

Ok, have reproduced it. Thanks

cy6erGn0m commented 5 years ago

The reason why it happens is that you have a watch pattern that matches everything (empty or /) that causes hot-reloading classloader to watch and load all the classes that causes this violation

cy6erGn0m commented 5 years ago

The root cause is explained here http://frankkieviet.blogspot.com/2009/03/javalanglinkageerror-loader-constraint.html

We already have similar/related workaround in ktor: we are skipping ktor core from child classloader but org.slf4j.Logger is not blacklisted so we have linkage error. We need to think more about possible solution.

User's workaround is to not include everything to watch list. Note that / pattern will include everything including JDK's classes that is not right. Please specify watch patterns more precisely.

cy6erGn0m commented 5 years ago

For now a temporary workaround is applied as per commit 87c71dd

cy6erGn0m commented 5 years ago

Fixed in 1.1.0

Ccixyj commented 5 years ago

Fixed in 1.1.0

this error also happend using WebSockets feature ktor version 1.1.1

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:71)
    at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Static.call(CallerImpl.kt:80)
    at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:106)
    at kotlin.reflect.jvm.internal.KCallableImpl.callDefaultMethod$kotlin_reflect_api(KCallableImpl.kt:152)
    at kotlin.reflect.jvm.internal.KCallableImpl.callBy(KCallableImpl.kt:110)
    at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.callFunctionWithInjection(ApplicationEngineEnvironmentReloading.kt:347)
    at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:297)
    at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.instantiateAndConfigureApplication(ApplicationEngineEnvironmentReloading.kt:273)
    at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createApplication(ApplicationEngineEnvironmentReloading.kt:126)
    at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.start(ApplicationEngineEnvironmentReloading.kt:245)
    at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:106)
    at BlogAppKt.main(BlogApp.kt:99)
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "io.ktor.application.ApplicationEvents.subscribe(Lio/ktor/application/EventDefinition;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/DisposableHandle;" the class loader (instance of io/ktor/server/engine/OverridingClassLoader$ChildURLClassLoader) of the current class, io/ktor/websocket/WebSockets$Feature, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for the method's defining class, io/ktor/application/ApplicationEvents, have different Class objects for the type kotlinx/coroutines/DisposableHandle used in the signature
    at io.ktor.websocket.WebSockets$Feature.install(WebSockets.kt:79)
    at io.ktor.websocket.WebSockets$Feature.install(WebSockets.kt:71)
    at io.ktor.application.ApplicationFeatureKt.install(ApplicationFeature.kt:59)
    at BlogAppKt.main(BlogApp.kt:49)
    ... 16 more
jamesward commented 5 years ago

Ran into this as well with:

java.lang.LinkageError: loader constraint violation: when resolving method "kotlinx.coroutines.io.CoroutinesKt.writer(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/io/ByteChannel;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/io/WriterJob;" the class loader (instance of io/ktor/server/engine/OverridingClassLoader$ChildURLClassLoader) of the current class, io/ktor/network/sockets/CIOReaderKt, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for the method's defining class, kotlinx/coroutines/io/CoroutinesKt, have different Class objects for the type kotlinx/coroutines/CoroutineScope used in the signature
jamesward commented 4 years ago

BTW, I resolved this by not setting the watchPaths when creating the embeddedServer.

omkar-tenkale commented 1 year ago

I faced this issue when deploying ktor server to digitalocean droplet using dokku had to disable development mode from application.conf and then it worked