为什么Play会为Selendroid的Netty' HttpRequest.headers()抛出NoSuchMethodError?

时间:2014-07-15 15:43:01

标签: java playframework-2.0 netty selendroid

好的,所以我的localhost:9000在一周前工作得很好,自从我将项目移到Eclipse后,我就收到了这个错误。即使我的代码处于最基本的形式,它也会产生一个由Play捕获的Netty错误。

这是我的错误:

 [info] play - Application started (Prod)
 [info] play - Listening for HTTP on /0.0.0.0:9000
 [error] p.nettyException - Exception caught in Netty
 java.lang.NoSuchMethodError: org.jboss.netty.handler.codec.http.HttpRequest.headers()Lorg/jboss/netty/handler/codec/http/HttpHeaders;
 at play.core.server.netty.PlayDefaultUpstreamHandler.getHeaders(PlayDefaultUpstreamHandler.scala:366) ~[na:na]
 at play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:87) ~[na:na]
 at com.typesafe.netty.http.pipelining.HttpPipeliningHandler.messageReceived(HttpPipeliningHandler.java:62) ~[na:na]
 at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:100) ~[na:na]
 at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) ~[na:na]
 [error] p.nettyException - Exception caught in Netty
 java.lang.NoSuchMethodError: org.jboss.netty.handler.codec.http.HttpRequest.headers()Lorg/jboss/netty/handler/codec/http/HttpHeaders;
 at play.core.server.netty.PlayDefaultUpstreamHandler.getHeaders(PlayDefaultUpstreamHandler.scala:366) ~[na:na]
 at play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:87) ~[na:na]
 at com.typesafe.netty.http.pipelining.HttpPipeliningHandler.messageReceived(HttpPipeliningHandler.java:62) ~[na:na]
 at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:100) ~[na:na]
 at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) ~[na:na]
 [error] p.nettyException - Exception caught in Netty
 java.lang.NoSuchMethodError: org.jboss.netty.handler.codec.http.HttpRequest.headers()Lorg/jboss/netty/handler/codec/http/HttpHeaders;
 at play.core.server.netty.PlayDefaultUpstreamHandler.getHeaders(PlayDefaultUpstreamHandler.scala:366) ~[na:na]
 at play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:87) ~[na:na]
 at com.typesafe.netty.http.pipelining.HttpPipeliningHandler.messageReceived(HttpPipeliningHandler.java:62) ~[na:na]
 at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:100) ~[na:na]
 at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) ~[na:na] 

以下是基本表单代码:

public class Application extends Controller /*implements Runnable*/ {

public static RequestBody print;
//private static RemoteWebDriver driver;
//private static int ok;

public static Result index() {
    return ok(index.render("Your new application is ready."));
}

// Step that prints the object once the JSON is received
@BodyParser.Of(BodyParser.Json.class)
public static Result receive(){
    JsonNode json = request().body().asJson();
    if(json == null)
        // As long as the json is null it will display this
        return badRequest("Expecting data");
    else{
        RequestBody body = request().body();
           print = body;
           return ok("Data received.\n" + body.asJson());
    }
}

public static Result show(){
    if(print == null){
        return ok("Expecting data.");
    }
    //(new Thread(new Application())).start();
    return ok(print.asJson());
}
}

1 个答案:

答案 0 :(得分:3)

tl; dr 在构建中使用evicted命令,excludeforce(),并在target/resolution-cache/reports/下使用非常有用的报告。不要忘记sbt-dependency-graph

正如Exclude specific transitive deps所说:

  

有时需要一些侦探工作来确定要排除的传递代表。

我经历过非常相似的问题,解决方案是使用Netty库的正确依赖(或者更确切地说排除一个让assembly通过)。

[microservice]> evicted
[info] Updating {file:/Users/jacek/work/.../}microservice...
[info] Resolving jline#jline;2.12 ...
[info] Done updating.
[warn] There may be incompatibilities among your library dependencies.
[warn] Here are some of the libraries that were evicted:
[warn]  * xml-apis:xml-apis:1.0.b2 -> 1.4.01 (caller: xerces:xercesImpl:2.11.0, dom4j:dom4j:1.6.1)
[warn]  * io.netty:netty:(3.6.6.Final, 3.6.3.Final) -> 3.9.3.Final (caller: com.typesafe.netty:netty-http-pipelining:1.1.2, com.typesafe.play:play_2.11:2.3.7, org.apache.cassandra:cassandra-all:2.0.8, com.netflix.astyanax:astyanax-cassandra:1.56.48)
[warn]  * joda-time:joda-time:1.6.2 -> 2.3 (caller: com.typesafe.play:play-json_2.11:2.3.7, com.netflix.astyanax:astyanax-core:1.56.48, com.typesafe.play:play_2.11:2.3.7, com.netflix.astyanax:astyanax-cassandra:1.56.48, com.netflix.astyanax:astyanax-recipes:1.56.48, com.netflix.astyanax:astyanax-thrift:1.56.48)
[warn]  * jline:jline:1.0 -> 2.11 (caller: com.tinkerpop:gremlin-groovy:3.0.0.M6, org.apache.cassandra:cassandra-all:2.0.8)
[success] Total time: 5 s, completed Feb 20, 2015 6:42:14 PM

正如您在上面的代码段中所注意到的那样,我在三个不同版本的Netty - 3.6.6.Final3.6.3.Final3.9.3.Final之间遇到依赖关系版本不匹配。

我需要选择3.6.6.Final,因此我使用force()作为我明确添加到构建中的版本(使用 build.sbt ):

libraryDependencies += "io.netty" % "netty" % "3.6.3.Final" force()

使用构建中的上述行,执行evicted显示:

[warn]  * io.netty:netty:(3.9.3.Final, 3.6.6.Final) -> 3.6.3.Final (caller: com.typesafe.netty:netty-http-pipelining:1.1.2, org.apache.cassandra:cassandra-all:2.0.8, com.typesafe.play:play_2.11:2.3.7, com.netflix.astyanax:astyanax-cassandra:1.56.48, my.company:microservice_2.11:0.6.1)

构建适用于上面输出(最后一个库)中出现的my.company:microservice_2.11:0.6.1

但是,有时您应该使用exclude删除冲突的依赖项,如下所示:

libraryDependencies ~= { _ map(m => m.exclude("commons-logging", "commons-logging")) }