Description
在代理日志中出现大量空指针异常:
An exception 'java.lang.NullPointerException' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception
追踪代码发现 HttpProxyClientHandler.java类中重写方法资源释放顺序导致:
@OverRide
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.channel().close();
clientChannel.close();
// clientChannel 被关闭资源后,再获取pipeline()导致
HttpProxyExceptionHandle exceptionHandle = ((HttpProxyServerHandler) clientChannel.pipeline()
.get("serverHandle")).getExceptionHandle();
exceptionHandle.afterCatch(clientChannel, ctx.channel(), cause);
}
修改顺序后正常:
@OverRide
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
HttpProxyExceptionHandle exceptionHandle = ((HttpProxyServerHandler) clientChannel.pipeline()
.get("serverHandle")).getExceptionHandle();
exceptionHandle.afterCatch(clientChannel, ctx.channel(), cause);
ctx.channel().close();
clientChannel.close();
}
Lots of null pointer exceptions in agent logs:
An exception 'java.lang.NullPointerException' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception
Tracing the code found that the resource release sequence of the overridden methods in the HttpProxyClientHandler.java class resulted in:
@OverRide
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.channel().close();
clientChannel.close();
// After the clientChannel resource is closed, pipeline() is obtained again.
HttpProxyExceptionHandle exceptionHandle = ((HttpProxyServerHandler) clientChannel.pipeline()
.get("serverHandle")).getExceptionHandle();
exceptionHandle.afterCatch(clientChannel, ctx.channel(), cause);
}
Normal after modifying the order:
@OverRide
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
HttpProxyExceptionHandle exceptionHandle = ((HttpProxyServerHandler) clientChannel.pipeline()
.get("serverHandle")).getExceptionHandle();
exceptionHandle.afterCatch(clientChannel, ctx.channel(), cause);
ctx.channel().close();
clientChannel.close();
}