netty/netty — Issue #205: channel.close().awaitUninterruptibly() hangs when exception is thrown in closeRequested()
Author: sureshlalvani
Created: 2012-02-27 23:24:59+00:00
State: open

I am a new netty user. I am trying to close connections on server side and seeing that the code hangs at channel.close().awaitUninterruptibly(). I throw an exception from closeRequested() method to produce the problem (in sample code given below).

I am using netty 3.3.1-final. Any help would be helpful.

package com.usairways.cbro.baggage.scanning.stomp;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

public class Experiment {

final static String host = "localhost";
final static int port = 61756;
final static ChannelGroup group = new DefaultChannelGroup();;

public static void main(String[] args) throws Exception {
ServerBootstrap serverBootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
serverBootstrap.setPipelineFactory(
new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("handler", new SimpleChannelHandler() {
@Override
public void closeRequested(ChannelHandlerContext ctx,
ChannelStateEvent e)
throws Exception {
System.out.println("close requested: " + e.getChannel());
throw new RuntimeException("test");
}

@Override
public void channelOpen(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
System.out.println("channel open: " + e.getChannel());
group.add(e.getChannel());
super.channelOpen(ctx, e);
}

@Override
public void channelClosed(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
System.out.println("channel closed: " + e.getChannel());
super.channelClosed(ctx, e);
}

@Override
public void exceptionCaught(
ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
System.out.println("exception caught: " + e.getChannel());
}
});
return pipeline;
}
});
Channel serverChannel = serverBootstrap.bind(new InetSocketAddress(port));

ClientBootstrap clientBootstrap = new ClientBootstrap(
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
return Channels.pipeline(new SimpleChannelHandler());
}
});

ChannelFuture f = clientBootstrap.connect(new InetSocketAddress(host, port));
f.awaitUninterruptibly();
serverChannel.close().awaitUninterruptibly();
System.out.println("after closing server channel");
for(Channel channel : group) {
// The channel is not closed and this will wait forever
channel.close().awaitUninterruptibly();
System.out.println("after closing client channel - this line is never printed");
}
System.out.println("end of program - this line is never printed");

}
}