问题
After upgrading from Play 2.4 to Play 2.5 on a sample app, when I run ./activator clean dist
, I get no errors however after going to a specific endpoint http://localhost:9000/java/proxy
, I'm receiving the following error:
[error] application -
! @72keog237 - Internal server error, for (GET) [/java/proxy] ->
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.lang.RuntimeException: There is no HTTP Context available from here.]]
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)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: java.util.concurrent.CompletionException: java.lang.RuntimeException: There is no HTTP Context available from here.
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)
... 5 common frames omitted
Caused by: java.lang.RuntimeException: There is no HTTP Context available from here.
at play.mvc.Http$Context.current(Http.java:62)
at play.mvc.Controller.response(Controller.java:81)
at controllers.JavaController$4.apply(JavaController.java:107)
at controllers.JavaController$4.apply(JavaController.java:103)
at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:602)
at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
at java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:443)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
I have been using the guide from the Replaced F.Promise with Java 8's CompletionStage replacing F.Promise, map, and flatMap with the suggested replacements from the previous link (reflected snippet of changes below).
public CompletionStage<Result> proxy() {
final CompletionStage<WSResponse> responsePromise = WS.url("http://example.com").get();
Logger.info("Before map");
final CompletionStage<Result> resultPromise = responsePromise.thenApplyAsync(
new Function<WSResponse, Result>() {
@Override
public Result apply(WSResponse wsResponse) {
Logger.info("Within map");
response().setContentType(wsResponse.getHeader("Content-Type"));
return ok(wsResponse.getBody());
}
}
);
When going back to 2.4, I don't get this error and the http://localhost:9000/java/proxy
endpoint works successfully.
After replacing the appropriate replacement calls in the proxy
method using this public sample app on github, I keep getting the no HTTP Context available
error above. I also get the same result with http://localhost:9000/java8/proxy
endpoint in the Java8Controller class.
I found others who have come across this problem and so far I've been able to conjecture that I need a HttpExecutionContext call and/or use supplyAsync although I've been having trouble transferring that knowledge to this example. Perhaps someone can give an example or two (or three) on how I may resolve this error? Any suggestions welcome, and thank you in advance.
回答1:
As per the Play Documentation, you must supply the HTTP execution context explicitly as an executor when using a Java CompletionStage inside an Action. So you can inject HTTP Context in your Action.
public class Application extends Controller {
@Inject HttpExecutionContext ec;
public CompletionStage<Result> index() {
someCompletableFuture.supplyAsync(() -> {
// do something with request()
}, ec.current());
}
}
Hope that helps.
来源:https://stackoverflow.com/questions/41608504/play-2-5-upgrade-error-completionexception-there-is-no-http-context-available