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.

UnsupportedOperationException: direct buffer when handling plugin channel message

See original GitHub issue

Originally I thought this was an issue with LuckPerms, but after reviewing the affected code it appears the issue lies on the side of Sponge. Code in question: https://github.com/lucko/LuckPerms/blob/master/sponge/src/main/java/me/lucko/luckperms/sponge/messaging/BungeeMessagingService.java#L86-L90
Original issue: lucko/LuckPerms#372

I am currently running…

  • SpongeForge version: 1.12-2397-7.0.0-BETA-2462 (problem has persisted through a lot of version. Don’t remember exactly when it started though)
  • Forge version: 14.21.1.2406
  • Java version: 1.8.0_131
  • Operating System: Debian GNU/Linux 9.0 (stretch)
  • Plugins/Mods: Minecraft, Minecraft Coder Pack, Forge Mod Loader, Minecraft Forge, OpenEye, SpongeAPI, SpongeForge, FoxCore, FoxGuard, Latch, NuVotifier, VotifierListener, Broadcast, BungeeTabListPlus-SpongeBridge, EconomyLite, FastAsyncWorldEdit, WorldEdit, Inventory Sync, LuckPerms, MMCTickets, ModBanner, Nucleus, PayDay, PlaceholderAPI, Prism, SkinsRestorer, SleepVote, Just Enough Items, AppleSkin, JourneyMap

What is the expected result?

The buffer of the bungee message being readable.

What is the current result?

The buffer of the bungee message being in an apparently unreadable state, thrwoing the following exception when trying to access, kicking the player the message has been sent through in the process.

[05:04:08] [Netty Epoll Server IO #1/FATAL] [Sponge]: SpongeRawDataInboundHandler exception
[05:04:08] [Netty Epoll Server IO #1/ERROR] [FML]: There was a critical exception handling a packet on channel lpuc
java.lang.UnsupportedOperationException: direct buffer
        at io.netty.buffer.PooledUnsafeDirectByteBuf.array(PooledUnsafeDirectByteBuf.java:343) ~[PooledUnsafeDirectByteBuf.class:?]
        at net.minecraft.network.PacketBuffer.readUTF(PacketBuffer.java:1838) ~[gy.class:?]
        at me.lucko.luckperms.sponge.messaging.BungeeMessagingService.handlePayload(BungeeMessagingService.java:88) ~[BungeeMessagingService.class:?]
        at org.spongepowered.mod.network.SpongeRawChannel.handlePacket(SpongeRawChannel.java:91) ~[SpongeRawChannel.class:1.12-2397-7.0.0-BETA-2457]
        at org.spongepowered.mod.network.SpongeRawDataInboundHandler.channelRead0(SpongeRawDataInboundHandler.java:50) ~[SpongeRawDataInboundHandler.class:1.12-2397-7.0.0-BETA-2457]
        at org.spongepowered.mod.network.SpongeRawDataInboundHandler.channelRead0(SpongeRawDataInboundHandler.java:36) ~[SpongeRawDataInboundHandler.class:1.12-2397-7.0.0-BETA-2457]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) ~[SimpleChannelInboundHandler.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[AbstractChannelHandlerContext.class:?]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) ~[DefaultChannelPipeline$HeadContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[AbstractChannelHandlerContext.class:?]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) ~[DefaultChannelPipeline.class:?]
        at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:274) ~[EmbeddedChannel.class:?]
        at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.func_148833_a(FMLProxyPacket.java:99) [FMLProxyPacket.class:?]
        at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:147) [gw.class:?]
        at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:49) [gw.class:?]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:?]
        at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleServerSideCustomPacket(NetworkDispatcher.java:445) [NetworkDispatcher.class:?]
        at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:267) [NetworkDispatcher.class:?]
        at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:74) [NetworkDispatcher.class:?]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:?]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293) [ByteToMessageDecoder.class:?]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267) [ByteToMessageDecoder.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:?]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293) [ByteToMessageDecoder.class:?]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267) [ByteToMessageDecoder.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:?]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293) [ByteToMessageDecoder.class:?]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267) [ByteToMessageDecoder.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:?]
        at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287) [IdleStateHandler.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) [DefaultChannelPipeline$HeadContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) [DefaultChannelPipeline.class:?]
        at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:1017) [AbstractEpollStreamChannel$EpollStreamUnsafe.class:?]
        at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:394) [EpollEventLoop.class:?]
        at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:299) [EpollEventLoop.class:?]
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) [SingleThreadEventExecutor$5.class:?]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]

Issue Analytics

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

github_iconTop GitHub Comments

2reactions
Mumfreycommented, Jul 18, 2017

Basically our current implementation calls .array() on ByteBufs in a few places unguarded by a call to .hasArray(), they’d need to be changed to support direct buffers as well.

Interestingly, this code was actually originally correct in @Deamon5550’s original commit and was actually broken by @Zidane in a later commit.

There’s also a slight issue in that ChannelBuf has an array() method without the corresponding hasArray(), but doesn’t declare the resulting UnsupportedOperationException which the underlying ByteBuf does, so consumers can be forgiven for not realising that calling array() can potentially raise an exception.

1reaction
kashikecommented, Jul 18, 2017

This wasn’t broken with https://github.com/SpongePowered/SpongeCommon/commit/5a9531b12f110332bc6ff3220f43dd0d042f0bc2#diff-b6508f10b836d49cb737ffa1f0ee594eR242, it was broken with the 1.12 upgrade.

1.12 upgraded netty to 4.1.9.Final from 4.0.23.Final.

During a decode with 4.0.23.Final, the following code path is taken:

	  at io.netty.buffer.UnpooledHeapByteBuf.<init>(UnpooledHeapByteBuf.java:45)
	  at io.netty.buffer.UnpooledByteBufAllocator.newHeapBuffer(UnpooledByteBufAllocator.java:43)
	  at io.netty.buffer.AbstractByteBufAllocator.heapBuffer(AbstractByteBufAllocator.java:136)
	  at io.netty.buffer.Unpooled.buffer(Unpooled.java:137)
	  at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:661)
	  at io.netty.buffer.WrappedByteBuf.readBytes(WrappedByteBuf.java:483)

If we have a look at AbstractByteBuf#readBytes(int), we see that it calls Unpooled#buffer(int, int) - we end up with a io.netty.buffer.UnpooledHeapByteBuf, which does allow array() to be called (so long as the array is accessible).

During a decode with 4.1.9.Final, the following code path is taken:

	  at io.netty.buffer.PoolArena$DirectArena.newByteBuf(PoolArena.java:775)
	  at io.netty.buffer.PoolArena.allocate(PoolArena.java:145)
	  at io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:320)
	  at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:181)
	  at io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:117)
	  at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:828)

Now, with 4.1.9.Final, AbstractByteBuf#readBytes(int) was changed to use the allocator rather than Unpooled#buffer(int, int) - we end up with a io.netty.buffer.PooledUnsafeDirectByteBuf, thanks to PoolArena#newByteBuf.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reflective setAccessible(true) disabled : KTOR-472
We already have the direct buffer constructor: unavailable message in the Netty log so java.lang.UnsupportedOperationException looks redundant.
Read more >
Reflective setAccessible(true) disabled - Stack Overflow
PlatformDependent0 - direct buffer constructor: unavailable java.lang.UnsupportedOperationException: Reflective setAccessible(true) disabled ...
Read more >
Bungee - Proxy - ProtocolSupportBungee | Page 5 - Spigot
UnsupportedOperationException : direct buffer at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:98)
Read more >
UnsupportedOperationException (Java Platform SE 8 )
Constructs a new exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which typically contains the class...
Read more >
Not available SonarCFamily plugin on Developer edition
processSelectedKey(NioEventLoop.java:644) at io.netty.channel.nio.NioEventLoop. ... direct buffer constructor: unavailable java.lang.
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