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.

ClassNotFoundException when using ServiceLoader

See original GitHub issue

Hey, while writing plugins for BungeeCord proxy I ran into a problem with ClassLoader. Plugins use the redisson library to create the network It works like this:

  1. BungeeCord loads available plugins
  2. One of the plugins contains the redisson library and connects to redis
  3. Another plugin use the previously loaded plugin with the library to synchronize the objects

All plugins are loaded using the same ClassLoader, so the same ClassLoader also loads the redisson library, and knows about classes that we serialize and keep in redis. Unfortunately the plugin that is loaded in step 3 throws a error like:

Exception in thread "main" org.redisson.client.RedisException: Unexpected exception while processing command
	at org.redisson.command.CommandAsyncService.convertException(CommandAsyncService.java:351)
	at org.redisson.command.CommandAsyncService.get(CommandAsyncService.java:148)
	at org.redisson.RedissonObject.get(RedissonObject.java:81)
	at org.redisson.RedissonBucket.get(RedissonBucket.java:104)
	at org.hesterq.redis.plugin.ExternalDataListener.tryGet(ExternalDataListener.java:22)
	at org.hesterq.redis.plugin.ExternalPlugin.enable(ExternalPlugin.java:31)
	at org.hesterq.redis.Server.main(Server.java:74)
Caused by: java.io.IOException: java.lang.ClassNotFoundException: org.hesterq.redis.plugin.ExternalData
	at org.redisson.codec.MarshallingCodec$3.decode(MarshallingCodec.java:153)
	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:358)
	at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:177)
	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:116)
	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:101)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508)
	at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: org.hesterq.redis.plugin.ExternalData
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at org.jboss.marshalling.AbstractClassResolver.loadClass(AbstractClassResolver.java:129)
	at org.jboss.marshalling.AbstractClassResolver.resolveClass(AbstractClassResolver.java:110)
	at org.jboss.marshalling.river.RiverUnmarshaller.doReadClassDescriptor(RiverUnmarshaller.java:1033)
	at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1366)
	at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:283)
	at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:216)
	at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41)
	at org.redisson.codec.MarshallingCodec$3.decode(MarshallingCodec.java:151)
	... 23 more

So I wrote small ServiceLoader application to reproduce that issue.

Steps to reproduce or test case https://github.com/HesterQ/RedisServer

  1. clone repo: https://github.com/HesterQ/RedisServer.git
  2. redis-cli config set notify-keyspace-events KEA
  3. ./test.sh for auto-install

or manually

  1. clone repo: https://github.com/HesterQ/RedisServer.git
  2. mvn clean install
  3. copy all generated plugin jars (RedisServer-WriterPlugin; RedisServer-RedisProviderPlugin; RedisServer-ReaderPlugin) to RedisServer-Server\target\plugins\
  4. redis-cli config set notify-keyspace-events KEA
  5. run RedisServer-Server-1.0.0-SNAPSHOT.jar

Redis version 6.0.10

Redisson version

<dependency>
	<groupId>org.redisson</groupId>
	<artifactId>redisson-all</artifactId>
	<version>3.15.1</version>
</dependency>

Redisson configuration

Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
Lorak-mmkcommented, Mar 25, 2021

set useThreadClassLoader = false in configuration.

Yep, that was the issue - we didn’t know about this option, thanks.

1reaction
mrnikocommented, Mar 25, 2021

set useThreadClassLoader = false in configuration.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ClassNotFoundException when using ServiceLoader in ...
Generally, a NoClassDefError (as opposed to a ClassNotFoundException ) occurs when a statically compiled class is not available at runtime ...
Read more >
ClassNotFoundException when using ServiceLoader in ...
Generally, a NoClassDefError (as opposed to a ClassNotFoundException ) occurs when a statically compiled class is not available at runtime ...
Read more >
JBoss.org Content Archive (Read Only)
I get an exception when I run WSProvide: $ wsprovide.sh -k -w -c classes -o classes -r jbossws -s jbossws com.mycompany.myapp.ws.
Read more >
jackson-kotlin dependency causes ClassNotFoundException ...
After a deeper look, the NoClassDefFoundError is raised by Java service loader that try to load KotlinModule which is itself a Kotlin class,...
Read more >
ServiceLoader (Java Platform SE 8 ) - Oracle Help Center
Creates a new service loader for the given service type, using the extension class loader. This convenience method simply locates the extension class...
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