玩之间的冲突!框架2.5和gRPC 0.13

DAN*_*Fan 6 playframework grpc

Play 2.5.0使用Netty 4.0.33,而gRPC需要Netty 4.1.0(支持http2),这会导致以下异常:

[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)
Run Code Online (Sandbox Code Playgroud)

删除所有gRPC代码后,它再次起作用.

我现在可以尝试一下快速修复吗?谢谢!

mar*_*ira 11

编辑:

播放2.6.0已发布,它正在使用Netty 4.1.

TL;博士

由于Netty 4和Netty 4.1之间的二进制不兼容,Play 2.5.0和gRPC不兼容.


这就是为什么它不适用于Play 2.5.0但适用于Play 2.4.0:

Play 2.5.0使用Netty版本4.0.33.Final,该版本声明(通过netty-reactive-streams版本1.0.2传递),如下所示:

<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>
Run Code Online (Sandbox Code Playgroud)

版本4.0.33.Finalasync-http-client4.0.34.Final传递的版本逐出,这些是Play 2.5.0使用的netty依赖项:

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
Run Code Online (Sandbox Code Playgroud)

另一方面播放2.4.6,只需要以下网络依赖:

io.netty:netty:3.8.0.Final
Run Code Online (Sandbox Code Playgroud)

因此,尽管Play 2.5.0依赖于许多较小的netty软件包,但Play 2.4.6仅依赖于单个netty软件包.这是因为Netty 4 改变了项目结构,将项目拆分为多个子项目,以便用户只需添加Netty所需的功能.更重要的是" Netty的软件包名称已从org.jboss.netty更改为io.netty ".

为什么这些变化在这里都很重要:

  1. gRPC与2.4.6之间没有依赖性冲突,因为gRPC不需要依赖性io.netty:netty,甚至不需要依赖性.因此,没有驱逐.
  2. 类级别没有冲突,因为类具有不同的包名称(org.jboss.nettyio.netty),然后具有不同的完全限定名称.他们被视为不同的阶级.

与Play 2.5.0存在冲突,因为Netty 4和Netty 4.1具有相同的依赖关系(然后4.0.34被4.1驱逐)并且因为 - 因为我们现在在这两个版本之间具有相同的完全限定类名 - 所以出现二进制不兼容性.

这是一个很长的解释,说没有办法让gRPC和Play 2.5.0现在与Netty一起工作.即使您决定使用Akka HTTP服务器后端,也有可能与Play WS发生冲突.