question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`Thread.currentThread().getContextClassLoader()` is null

See original GitHub issue

Way to reproduce

Just get ClassLoader in Handler

public class HelloServiceHandler implements HelloService.Iface {
    @Override
    public String sayHi(String name) throws TException {
        // classLoader is null
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        return "Hi," + name;
    }
}

Impact

Some third library required Thread.currentThread().getContextClassLoader() to get classloader, this will cause error in service.

Reason

When create Thread, contextClassLoader will get from parent thread, but currently the parent thread is netty thread, there’s no contextClassLoader.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:13 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
ikhooncommented, Mar 16, 2022

there’s multiple co-routines trying to set and unset the contextClassLoader

Are you using Kotlin coroutines with Armeria’s annotated service or gRPC-Kotlin? We may inject a custom coroutine context to push and pop a ContextClassLoader. For example:

  • Defines a coroutine context
    class ContextClassLoaderCoroutineContext() : ThreadContextElement<SafeCloseable>, AbstractCoroutineContextElement(Key) {
    
        companion object Key : CoroutineContext.Key<ContextClassLoaderCoroutineContext>
    
        override fun updateThreadContext(context: CoroutineContext): SafeCloseable {
          val currentThread = Thread.currentThread()
          val oldContextClassLoader = currentThread.contextClassLoader
          currentThread.contextClassLoader = javaClass.classLoader
          return SafeCloseable {
            currentThread.contextClassLoader = oldContextClassLoader
          }
        }
    
        override fun restoreThreadContext(context: CoroutineContext, oldState: SafeCloseable) {
          oldState.close()
        }
    }
    
  • for gRPC-Kotlin, we can use CoroutineContextServerInterceptor to inject the coroutine context.
  • for Armeria annotated service, we can use CoroutineContextService.
2reactions
trustincommented, Jan 27, 2021

As a workaround, you can do this:

public class HelloServiceHandler implements HelloService.Iface {
    @Override
    public String sayHi(String name) throws TException {
        Thread currentThread = Thread.currentThread();
        ClassLoader oldContextClassLoader = currentThread.getContextClassLoader();
        currentThread.setContextClassLoader(getClass().getClassLoader());
        try {
            // ...
        } finally {
            currentThread().setContextClassLoader(oldContextClassLoader);
        }
    }
}

Please let me know if this solves your problem.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Thread.getContextClassLoader() == null? - java - Stack Overflow
Java threads created from JNI code in a non-java thread have null ... Also in such context Thread.currentThread() returns null.
Read more >
Thread.currentThread().getContextClassLoader() returns null ...
This returns null in the Windows image, but in the linux and MacOS images it returns a non-null object. The specific line where...
Read more >
63612 – PooledConnection#connectUsingDriver, Thread ...
1. If "Thread.currentThread().getContextClassLoader()" is null, it essentially means that this thread is not associated with a web application.
Read more >
Example usage for java.lang Thread getContextClassLoader
In this page you can find the example usage for java.lang Thread getContextClassLoader. Prototype. @CallerSensitive public ClassLoader getContextClassLoader().
Read more >
java.lang.Thread.getContextClassLoader java code examples
invoker, Invocation invocation) throws RpcException { ClassLoader ocl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found