Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从播放2.4转换到播放2.5时异步操作中的NullPointerException_Java_Playframework_Nullpointerexception_Playframework 2.5 - Fatal编程技术网

Java 从播放2.4转换到播放2.5时异步操作中的NullPointerException

Java 从播放2.4转换到播放2.5时异步操作中的NullPointerException,java,playframework,nullpointerexception,playframework-2.5,Java,Playframework,Nullpointerexception,Playframework 2.5,我正在将Play2.4项目移植到Play2.5(.18)。我遇到了一个虚假的NullPointerException我找不到原因。这是堆栈跟踪: ! @76g5ina3j - Internal server error, for (POST) [/.../tokens] -> play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.lang.NullP

我正在将Play2.4项目移植到Play2.5(.18)。我遇到了一个虚假的
NullPointerException
我找不到原因。这是堆栈跟踪:

! @76g5ina3j - Internal server error, for (POST) [/.../tokens] ->

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.lang.NullPointerException]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:293)
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:220)
    at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
    at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
    at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:100)
Caused by: java.util.concurrent.CompletionException: java.lang.NullPointerException
    at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
    at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
    at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:604)
    at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
    at java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:443)
Caused by: java.lang.NullPointerException: null
    at akka.stream.scaladsl.RunnableGraph.run(Flow.scala:350)
    at akka.stream.scaladsl.Source.runWith(Source.scala:81)
    at akka.stream.javadsl.Source.runWith(Source.scala:528)
    at akka.stream.javadsl.Source.runFold(Source.scala:539)
    at play.http.HttpEntity.consumeData(HttpEntity.java:58)
正如您所看到的,堆栈跟踪没有任何对程序中代码行的引用,只提到了框架。我已经尽了最大的努力。播放操作是使用
CompletableFuture
supplyAsync
以及几个
thenApply()
阶段异步实现的。助手类最终通过调用

return Controller.status(some_resultcode);
最终的NPE原因始于
HttpEntity.consumerdata()
,并在游戏的Scala部分和Akka框架中深入结束。该
RunnableGraph.run()方法读取

def run()(implicit materializer: Materializer): Mat = materializer.materialize(this)
虽然这肯定比我的Scala知识多出了好几个数量级,但我的结论是这里唯一的
null
东西可能是神秘的
materializer
,不管它是什么。它来自哪里?它有什么好处?它怎么可能是空的

我试图用一种非常简单的方法重现这个问题:

public CompletionStage<Result> version() {
  return CompletableFuture
    .supplyAsync(()->"2")
    .thenApplyAsync(version->ok("Server v"+version));
}
public CompletionStage版本(){
返回可完成的未来
.supplyAsync(()->“2”)
.ThenApplySync(版本->确定(“服务器v”+版本));
}
不幸的是,这个操作没有问题,所以到目前为止,我还没有一个关于这个问题的简化的测试


我现在有点迷路了。有人能给我解释一下发生了什么以及如何解决这个问题吗?

好的,找到了这个。经过更深入的调查,情况有所不同。事实上,行动本身并不是问题所在。控制器如下所示:

@With(OurLogger.class)
public class OurController extends Controller {

  public CompletionStage<Result> ourAction() {
    return CompletableFuture.supplyAsync(()->...);
  }
}
问题是调用了
JavaResultTextRactor.getBody()
。在Play 2.4中,它只获得两个参数。剧本2.5增加了第三个——这个神秘的
物化器
,据我所知,它编纂了一些阿克卡管道的概念。在Play 2.5中使代码可编译时,一位同事刚刚添加了
null
作为第三个参数,而正是
null
是框架内部的Akka代码后来偶然发现的

解决方案位于的答案部分,并导致对
OurLogger
进行以下更改:

public class OurLogger extends Action.Simple {

  @Inject Materializer materializer;

  private Result logResult(Result result) {
    System.err.println("Result body: "+
      JavaResultExtractor.getBody(result,1,materializer).utf8String());
  }

  // call() method unchanged
}

如果(a)Play migration docs提到了这个
Materializer
东西和/或(b)错误堆栈跟踪中只出现了这个
getBody()
调用的一点点提示,我会更快地发现问题。这是大海捞针搜索的两天…

在play framework google group中,你可能会更幸运:
public class OurLogger extends Action.Simple {

  @Inject Materializer materializer;

  private Result logResult(Result result) {
    System.err.println("Result body: "+
      JavaResultExtractor.getBody(result,1,materializer).utf8String());
  }

  // call() method unchanged
}