2013-07-04 7 views
1

다음은 시나리오입니다.재생 프레임 워크 - java.nio.channels.ClosedChannelException

Play 프레임 워크를 사용하고 있습니다. 주어진 처리기 내에서 재생 프레임 워크는 내 API 웹 서비스를 호출하고 API 응답을 클라이언트에 반환합니다. 클라이언트가 Ajax 호출을 통해 핸들러를 호출 중입니다. 때로는 응답이 잘되지만 종종 클라이언트 측에서 오류 응답을 보게됩니다. 재생 프레임 워크의 로그를 확인하면 java.nio.channels.ClosedChannelException이 표시됩니다.

Play 2.1.1을 사용하고 있습니다. 내 API 웹 서비스가 localhost : 8888에서 실행 중입니다. Play 프레임 워크가 9000에서 실행 중입니다. API 서비스 응답이 정확합니다. 재생 프레임 워크는 또한 로그를 볼 수 있도록 콜백을 올바르게 실행합니다. 오류는 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([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