2013-07-04 329 views
1

這裏是場景。Play框架 - java.nio.channels.ClosedChannelException

我正在使用Play框架。在給定的處理函數中,play框架調用我的API webservice並將API響應返回給客戶端。客戶端通過Ajax調用來調用處理程序。有時候響應很好,但我經常在客戶端看到錯誤響應。檢查播放框架的日誌,我看到一個java.nio.channels.ClosedChannelException。

我正在使用Play 2.1.1。 我的API Webservice正在localhost:8888上運行。 Play框架在9000上運行。 API服務響應正確。 Play框架也正確執行回調,因爲我可以看到日誌。 ok()調用已從Play開始後發生錯誤。

以下是失敗的請求錯誤日誌 -

[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([email protected]),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:[email protected] 
[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); 
} 

處理器的名稱是addInterest。

任何可能在這裏發生的指針?

回答

1

java.nio.channels.ClosedChannelException

這意味着關閉了通道,然後繼續使用它。

+0

對,例如,瀏覽器現在關閉,服務器仍然向消失的客戶端發送消息。 – Twistleton

+0

@Twistleton錯誤。這會導致「連接重置」。這是由應用程序關閉自己的頻道引起的。 – EJP