Play 2.5.0 uses Netty 4.0.33, while gRPC requires Netty 4.1.0 (for http2 support), which causes the following exception:
[error] p.c.s.n.PlayRequestHandler - Exception caught in Netty
java.lang.AbstractMethodError: null
at io.netty.util.ReferenceCountUtil.touch(ReferenceCountUtil.java:73)
at io.netty.channel.DefaultChannelPipeline.touch(DefaultChannelPipeline.java:84)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:154)
at com.typesafe.netty.http.HttpStreamsHandler.channelRead(HttpStreamsHandler.java:131)
at com.typesafe.netty.http.HttpStreamsServerHandler.channelRead(HttpStreamsServerHandler.java:96)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:154)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
[error] p.c.s.n.PlayRequestHandler - Exception caught in Netty
java.util.NoSuchElementException: http-handler-body-publisher
at io.netty.channel.DefaultChannelPipeline.getContextOrDie(DefaultChannelPipeline.java:1050)
at io.netty.channel.DefaultChannelPipeline.remove(DefaultChannelPipeline.java:379)
at com.typesafe.netty.http.HttpStreamsHandler.handleReadHttpContent(HttpStreamsHandler.java:191)
at com.typesafe.netty.http.HttpStreamsHandler.channelRead(HttpStreamsHandler.java:167)
at com.typesafe.netty.http.HttpStreamsServerHandler.channelRead(HttpStreamsServerHandler.java:96)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:154)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
After I remove all gRPC codes, it works again.
Is there any quick fix that I can try now? Thanks!
Play 2.6.0 was released, and it is using Netty 4.1.
Play 2.5.0 and gRPC are not compatible due to binary incompatibilities between Netty 4 and Netty 4.1.
Here is why it doesn't work with Play 2.5.0 but works with Play 2.4.0:
Play 2.5.0 uses Netty version 4.0.33.Final
, which is declared (transitively via netty-reactive-streams version 1.0.2) like this:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
<version>4.0.33.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
<version>4.0.33.Final</version>
</dependency>
Version 4.0.33.Final
is evicted by version 4.0.34.Final
which was added transitively by async-http-client and these are the netty dependencies used by Play 2.5.0:
io.netty:netty-buffer:4.0.34.Final
io.netty:netty-codec-http:4.0.34.Final
io.netty:netty-codec:4.0.34.Final
io.netty:netty-common:4.0.34.Final
io.netty:netty-handler:4.0.34.Final
io.netty:netty-transport:4.0.34.Final
Play 2.4.6, on the other side, requires just the following netty dependency:
io.netty:netty:3.8.0.Final
So, while Play 2.5.0 depends on a lot of smaller netty packages, Play 2.4.6 depends just on a single netty package. That is because Netty 4 changed the project structure to split the project into multiple subprojects so that a user can add just the necessary features from Netty. And even more important, "the package name of Netty has been changed from org.jboss.netty to io.netty".
Why are these changes both relevant here?
io.netty:netty
, not even transitively. Because of that, there is no eviction.org.jboss.netty
and io.netty
) and then distinct full qualified names. Therefore, they are treated as different classes.There are conflicts with Play 2.5.0 because Netty 4 and Netty 4.1 have both the same dependencies artifactId
(then 4.1 version evicts 4.0.34) and because - since we now have the same full qualified class names between these two versions - binaries incompatibilities arise.
That is a long explanation to say that there is no way to make gRPC and Play 2.5.0 work together right now with Netty. Even if you decide to use Akka HTTP server backend, there is a chance of conflict with Play WS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With