1

これがシナリオです。

Play フレームワークを使用しています。指定されたハンドラー内で、play フレームワークは API Web サービスを呼び出し、API 応答をクライアントに返します。クライアントは、Ajax 呼び出しを介してハンドラーを呼び出しています。応答が正常に返されることもありますが、クライアント側でエラー応答が表示されることがよくあります。Play フレームワークのログを確認すると、java.nio.channels.ClosedChannelException が表示されます。

Play 2.1.1 を使用しています。私の API Web サービスは localhost:8888 で実行されています。Play フレームワークは 9000 で実行されています。API サービスの応答は正しいです。ログを見ると、Play フレームワークも Callback を正しく実行します。Play から ok() 呼び出しが行われた後にエラーが発生します。

失敗したリクエストのエラー ログは次のとおりです。

[debug] application - find...
[debug] application - id = 647110558
[trace] c.jolbox.bonecp - Check out connection [9 leased]
[trace] c.jolbox.bonecp - Check in connection [9 leased]
[debug] application - socialUser = SocialUser(UserId(647110558,facebook),Arvind,Batra,Arvind Batra,Some(arvindbatra@gmail.com),null,AuthenticationMethod(oauth2),null,Some(OAuth2Info(CAAHNVOUuNZAEBAMa3CPLUEsZA2Tp5xWGXylO9HggBY0TCfwsIn4iGUdlRMpuNPLxYcObKO5ZBZCU0ghS9ymHZC3s9YXpsfPix9AM1EhNyETvDR85HHYg8j7JO0h2WzGZBsKJdbFPhPmkD6ZBZAq6KTT8RLSQrmpfnHQZD,null,null,null)),null)
[info] application - Calling interest for fff
[info] application - user is not null
[trace] c.jolbox.bonecp - Check out connection [9 leased]
[info] application - interest=fff, userInfo:models.EBUser@14a420e1
[info] application - http://localhost:8888/api/add_interest/1/fff
[debug] c.n.h.c.p.n.NettyAsyncHttpProvider - Using cached Channel [id: 0x9d1dee2d, /127.0.0.1:50316 => localhost/127.0.0.1:8888]
 for uri http://localhost:8888/api/add_interest/1/fff
    [debug] c.n.h.c.p.n.NettyAsyncHttpProvider - 
Using cached Channel [id: 0x9d1dee2d, /127.0.0.1:50316 => localhost/127.0.0.1:8888]
 for request 
DefaultHttpRequest(chunked: false)
GET /api/add_interest/1/fff HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept: */*    User-Agent: NING/1.0

[debug] c.n.h.c.p.n.NettyAsyncHttpProvider -

Request DefaultHttpRequest(chunked: false)
GET /api/add_interest/1/fff HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept: */*
User-Agent: NING/1.0

Response DefaultHttpResponse(chunked: true)
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Thu, 04 Jul 2013 12:14:40 GMT
Transfer-Encoding: chunked

[debug] c.n.h.c.p.n.NettyConnectionsPool - Adding uri: http://localhost:8888 for channel [id: 0x9d1dee2d, /127.0.0.1:50316 => localhost/127.0.0.1:8888]
[info] application - {"status":"success"}
[info] application - {"status":"ok","exists":false}
[trace] play - Sending simple result: SimpleResult(200, Map(Content-Type -> application/json; charset=utf-8, Set-Cookie -> ))
[debug] play - java.nio.channels.ClosedChannelException
[trace] application - Exception caught in Netty
java.nio.channels.ClosedChannelException: null
  at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:409) ~[netty.jar:na]
  at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:127) ~[netty.jar:na]
  at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:99) ~[netty.jar:na]
  at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:36) ~[netty.jar:na]
  at org.jboss.netty.channel.Channels.write(Channels.java:725) ~[netty.jar:na]
  at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.doEncode(OneToOneEncoder.java:71) ~[netty.jar:na]
[debug] c.n.h.c.p.n.NettyConnectionsPool - Entry count for : http://localhost:8888 : 2

ここに私のサンプルコードがあります -

  public static Result addInterestCallback(WS.Response response) {
    if (response == null) {

      return badRequest();
    }
    ObjectNode result = (ObjectNode) response.asJson();
    try {
      Logger.info(result.toString());

      if (result.has("status")) {
        String status = result.get("status").getTextValue();
        if(status.equals("error")) {
          result.put("error", "Oops, cannot process your request. Sorry.");
          Logger.info("error");
          return badRequest(result);
        }
        else if(status.equals("exists")) {
          result.put("exists",true);
        }
        else {
          result.put("exists",false);
        }
        result.put("status", "ok");
      } else {
        //do something
        Logger.info("result has no status");
      }
      Logger.info(result.toString());
    } catch (Exception e) {
      e.printStackTrace();
    }

    return ok(result);

  }
  @BodyParser.Of(BodyParser.Json.class)
  @SecureSocial.UserAwareAction
  public static Result addInterest() {

    JsonNode json = request().body().asJson();
    String interestName = json.findPath("interestName").getTextValue();
    Logger.info("Calling interest for " + interestName);

    Identity user = (Identity) ctx().args.get(SecureSocial.USER_KEY);
    if (user == null) {
      ObjectNode result = Json.newObject();
      result.put("error", "requires-login");
      Http.Context ctx = Http.Context.current();
      ctx.flash().put("error", play.i18n.Messages.get("securesocial.loginRequired"));
      result.put("redirect", RoutesHelper.login().absoluteURL(ctx.request(), IdentityProvider.sslEnabled()));
      return ok(result);
    }
    Logger.info("user is not null");
    if(interestName == null) {
      ObjectNode result = Json.newObject();
      result.put("error", "Empty input");
      return badRequest(result);
    }
    //get user
    EBUser ebUser = Application.getEBUser();
    Logger.info("interest="+interestName+", userInfo:" + ebUser.toString());

    //Call addInterst API.
    String apiEndpoint = Play.application().configuration().getString(AppConstants.EB_API_ENDPOINT);
    String url = "";
    try {
      url = apiEndpoint + "add_interest/" + ebUser.getId() + "/" + URLEncoder.encode(interestName, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
      ObjectNode result = Json.newObject();
      result.put("error", "Cant parse interest properly");
      Logger.info("error " + result.toString());
      return badRequest(result);
    }

    Logger.info(url);
    Promise<WS.Response> promiseOfAPI = WS.url(url).get();
    Promise<Result>  promiseOfResult =  promiseOfAPI.map(
        new Function<WS.Response, Result>() {
          @Override
          public Result apply(WS.Response response) throws Throwable {
            return addInterestCallback(response);
          }
        });

    return async(promiseOfResult);
}

Handler の名前は addInterest です。

ここで何が起こっている可能性があるかについての指針はありますか?

4

1 に答える 1