ClassNotFoundException when using ServiceLoader
See original GitHub issueHey, 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:
- BungeeCord loads available plugins
- One of the plugins contains the redisson library and connects to redis
- 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
- clone repo: https://github.com/HesterQ/RedisServer.git
- redis-cli config set notify-keyspace-events KEA
- ./test.sh for auto-install
or manually
- clone repo: https://github.com/HesterQ/RedisServer.git
- mvn clean install
- copy all generated plugin jars (RedisServer-WriterPlugin; RedisServer-RedisProviderPlugin; RedisServer-ReaderPlugin) to RedisServer-Server\target\plugins\
- redis-cli config set notify-keyspace-events KEA
- 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:
- Created 3 years ago
- Comments:6 (3 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Yep, that was the issue - we didn’t know about this option, thanks.
set
useThreadClassLoader
=false
in configuration.