Playframework 游戏之间的冲突!框架2.5和gRPC 0.13

Playframework 游戏之间的冲突!框架2.5和gRPC 0.13,playframework,grpc,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.net

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)
在我删除所有gRPC代码后,它再次工作

我现在可以试试什么快速修复方法吗?谢谢

编辑: ,它正在使用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
,其声明(通过传递)如下:

<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>
另一方面,重头戏2.4.6只需要以下净相关性:

io.netty:netty:3.8.0.Final
因此,虽然Play 2.5.0依赖于许多较小的netty包,但Play 2.4.6只依赖于单个netty包。这是因为Netty 4需要将项目拆分为多个子项目,以便用户可以从Netty中添加必要的功能。更重要的是,“Netty的包名已从org.jboss.Netty更改为io.Netty

为什么这些变化都与此相关

  • gRPC与2.4.6之间没有依赖冲突,因为gRPC不需要依赖
    io。netty:netty
    ,甚至不需要传递。因此,没有驱逐
  • 在类级别没有冲突,因为类具有不同的包名(
    org.jboss.netty
    io.netty
    ),然后是不同的全限定名。因此,它们被视为不同的类
  • Play 2.5.0与Play 2.5.0存在冲突,因为Netty 4和Netty 4.1都具有相同的依赖项
    artifactId
    (然后4.1版本淘汰了4.0.34),并且因为-由于我们现在在这两个版本之间具有相同的完全限定类名-二进制文件不兼容问题出现


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

    我在使用Java时也遇到过这种情况。您是否使用gRPC客户端或服务器接口与Play服务器连接?如果您只是使用一个客户端,您可以通过使用OKHTTP客户端版本而不是依赖Netty的版本来克服这一问题

    如果你使用的是服务器,我想你可能会走运。你可以试着把内蒂排除在gRPC之外,希望这个游戏的版本足够了。只需将excludeAll ExcludeRule(organization=“io.netty”)添加到gRPC导入

    以下是play邮件列表中关于该主题的一条线索,但他们目前对该主题没有任何更改:

    您还可以使用maven shade插件重新定位netty软件包名称,以避免与早期版本冲突


    以couchbase jvm核心库为例。

    Netty 4.0.33和Netty 4.1.0不兼容二进制文件。您可以尝试使用4.0.33版本(不推荐使用),但我怀疑它是否有效。看起来您需要gRPC的替代品。@marcospereira force 4.0.33无法工作,因为gRPC需要http2,这是netty 4.1.0中的一项新功能。我尝试使用netty 4.1.0编译Play 2.5,但失败了。因此,我现在降级到Play 2.4。它与Play 2.4一起工作吗?@marcospereira是的,它工作。我有同样的问题,但与不同的库:Redisson v3.5.7。我在Scala 2.11和sbt 0.13上。也许我对此无能为力。难道不可能使用不同的类加载器来解决这个问题吗?用于play和grpc,这样每个类加载器都可以加载他们需要的任何东西…所以基本上你可以让play加载它需要的任何东西,然后为grpc创建一个类加载器,并确保运行grpc的任何线程都使用grpc类加载器。。。也许这样做会很糟糕,特别是考虑到开发和生产环境。我需要你的意见,我正在考虑这样做。首先,dev/prod环境可能有什么问题?如果它在dev上工作,那么prod为什么会有什么不同呢?第二个我想到的解决方案是创建一个方面,它将用around方面包装任何grpc实例化或执行,该方面将在执行之前设置适当的类加载器,并在执行之后设置原始类加载器。。。你认为这样行吗?@vach在这里看到我最后一次编辑。游戏2.6.0将与Netty 4.1一起发布。
    io.netty:netty:3.8.0.Final