diff --git a/src/main/java/org/jboss/netty/channel/ChannelHandler.java b/src/main/java/org/jboss/netty/channel/ChannelHandler.java index 24f33b5c62..5808bb1e0b 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelHandler.java +++ b/src/main/java/org/jboss/netty/channel/ChannelHandler.java @@ -15,6 +15,13 @@ */ package org.jboss.netty.channel; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + import org.jboss.netty.bootstrap.Bootstrap; /** @@ -92,6 +99,7 @@ import org.jboss.netty.bootstrap.Bootstrap; * In such a case, you can use an attachment which is provided by * {@link ChannelHandlerContext}: *
+ * {@literal @Sharable} * public class DataServerHandler extends SimpleChannelHandler { * * public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { @@ -137,6 +145,7 @@ import org.jboss.netty.bootstrap.Bootstrap; * ... * } * + * {@literal @Sharable} * public class DataServerHandler extends SimpleChannelHandler { * public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { * Channel ch = e.getChannel(); @@ -163,6 +172,23 @@ import org.jboss.netty.bootstrap.Bootstrap; * } ** + *
+ * In the examples above which used an attachment or a {@link ChannelLocal}, + * you might have noticed the {@literal @Sharable} annotation. + *
+ * If a {@link ChannelHandler} is annotated with the {@literal @Sharable} + * annotation, it means you can create an instance of the handler just once and + * add it to one or more {@link ChannelPipeline}s multiple times without + * a race condition. + *
+ * If this annotation is not specified, it is safe to create a new handler + * instance every time you add it to a pipeline because it has unshared state + * such as member variables. + *
+ * This annotation is provided for documentation purpose, just like + * the JCIP annotations. + * *
* Please refer to the {@link ChannelEvent} and {@link ChannelPipeline} to find @@ -178,5 +204,28 @@ import org.jboss.netty.bootstrap.Bootstrap; * @apiviz.exclude ^org\.jboss\.netty\.handler\..*$ */ public interface ChannelHandler { - // This is a tag interface. + + /** + * Indicates that the same instance of the annotated {@link ChannelHandler} + * can be added to one or more {@link ChannelPipeline}s multiple times + * without a race condition. + *
+ * If this annotation is not specified, it is safe to create a new handler + * instance every time you add it to a pipeline because it has unshared + * state such as member variables. + *
+ * This annotation is provided for documentation purpose, just like + * the JCIP annotations. + * + * @author The Netty Project + * @author Trustin Lee + * @version $Rev$, $Date$ + */ + @Inherited + @Documented + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.RUNTIME) + public @interface Sharable { + // no value + } } diff --git a/src/main/java/org/jboss/netty/channel/ChannelPipelineCoverage.java b/src/main/java/org/jboss/netty/channel/ChannelPipelineCoverage.java index db4542cbb2..1ff3c03fcb 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelPipelineCoverage.java +++ b/src/main/java/org/jboss/netty/channel/ChannelPipelineCoverage.java @@ -21,186 +21,12 @@ import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.util.concurrent.ConcurrentMap; + +import org.jboss.netty.channel.ChannelHandler.Sharable; /** - * Specifies if the same instance of the annotated {@link ChannelHandler} type - * can be added to more than one {@link ChannelPipeline}. - *
- * All handler types are expected to specify this annotation. Otherwise you - * will be warned in runtime. Only two values are allowed for this annotation: - * {@code "all"} and {@code "one"}. - *
- * Please note that this annotation does not prevent a handler annotated with - * the value {@code "one"} from being added to more than one pipeline. This - * annotation is used for documentation purpose only. - * - *
- * public class StatelessHandler extends SimpleChannelHandler { - * - * // No state properties - you are safe to add the same instance to - * // multiple pipelines. - * - * public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { - * // Prepend a length field to the message. - * ChannelBuffer body = (ChannelBuffer) e.getMessage(); - * ChannelBuffer header = ChannelBuffers.buffer(4); - * header.writeInt(body.readableBytes()); - * - * // Create a message prepended with the header and send a new event. - * ChannelBuffer message = ChannelBuffers.wrappedBuffer(header, body); - * Channels.fireMessageReceived(ctx, message, e.getRemoteAddress()); - * } - * ... - * } - *- * - * Please note that the handler annotated with {@code "all"} can even be added - * to the same pipeline more than once: - * - *
- * ChannelPipeline p = ...; - * StatelessHandler h = ...; - * p.addLast("handler1", h); - * p.addLast("handler2", h); - *- * - *
- * public class StatefulHandler extends SimpleChannelHandler { - * - * // Stateful property - adding the same instance to multiple pipelines - * // can lead to a race condition. - * private int messageId; - * - * public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { - * // Prepend a message ID and length field to the message. - * ChannelBuffer body = (ChannelBuffer) e.getMessage(); - * ChannelBuffer header = ChannelBuffers.buffer(8); - * header.writeInt(messageId); - * header.writeInt(body.readableBytes()); - * - * // Update the stateful property. - * messageId ++; - * - * // Create a message prepended with the header and send a new event. - * ChannelBuffer message = ChannelBuffers.wrappedBuffer(header, body); - * Channels.fireMessageReceived(ctx, message, e.getRemoteAddress()); - * } - * ... - * } - * - * // Create a new handler instance per channel. - * public class MyPipelineFactory implements ChannelPipelineFactory { - * - * public ChannelPipeline getPipeline() { - * ChannelPipeline p = Channels.pipeline(); - * p.addLast("handler", new StatefulHandler()); - * } - * } - *- * - *
- * The following is an example that uses the context attachment: - *
- * public class StatefulHandler extends SimpleChannelHandler { - * - * public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) { - * // Initialize the message ID counter. - * // Please note that the attachment (the counter in this case) will be - * // dereferenced and marked for garbage collection automatically on - * // disconnection. - * ctx.setAttachment(Integer.valueOf(0)); - * } - * - * public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { - * // Fetch the current message ID. - * int messageId = ((Integer) ctx.getAttachment()).intValue(); - * - * // Prepend a message ID and length field to the message. - * ChannelBuffer body = (ChannelBuffer) e.getMessage(); - * ChannelBuffer header = ChannelBuffers.buffer(8); - * header.writeInt(messageId); - * header.writeInt(body.readableBytes()); - * - * // Update the stateful property. - * ctx.setAttachment(Integer.valueOf(messageId + 1)); - * - * // Create a message prepended with the header and send a new event. - * ChannelBuffer message = ChannelBuffers.wrappedBuffer(header, body); - * Channels.fireMessageReceived(ctx, message, e.getRemoteAddress()); - * } - * ... - * } - *- * - * and here's another example that uses a map: - *
- * public class StatefulHandler extends SimpleChannelHandler { - * - * private final ConcurrentMap<ChannelHandlerContext, Integer> messageIds = - * new ConcurrentHashMap<ChannelHandlerContext, Integer>(); - * - * public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) { - * // Initialize the message ID counter. - * messageIds.put(ctx, Integer.valueOf(0)); - * } - * - * public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) { - * // Remove the message ID counter from the map. - * // Please note that the context attachment does not need this step. - * messageIds.remove(ctx); - * } - * - * public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { - * // Fetch the current message ID. - * int messageId = messageIds.get(ctx).intValue(); - * - * // Prepend a message ID and length field to the message. - * ChannelBuffer body = (ChannelBuffer) e.getMessage(); - * ChannelBuffer header = ChannelBuffers.buffer(8); - * header.writeInt(messageId); - * header.writeInt(body.readableBytes()); - * - * // Update the stateful property. - * messageIds.put(ctx, Integer.valueOf(messageId + 1)); - * - * // Create a message prepended with the header and send a new event. - * ChannelBuffer message = ChannelBuffers.wrappedBuffer(header, body); - * Channels.fireMessageReceived(ctx, message, e.getRemoteAddress()); - * } - * ... - * } - *- * - * Please note that the examples above in this section assume that the handlers - * are added before the {@code channelOpen} event and removed after the - * {@code channelClosed} event. The initialization and removal of the message - * ID property could have been more complicated otherwise. - * + * @deprecated Use the {@link Sharable} annotation instead. + * @author The Netty Project * @author Trustin Lee * diff --git a/src/main/java/org/jboss/netty/example/discard/DiscardClientHandler.java b/src/main/java/org/jboss/netty/example/discard/DiscardClientHandler.java index d7b04d269f..9a991a8bcf 100644 --- a/src/main/java/org/jboss/netty/example/discard/DiscardClientHandler.java +++ b/src/main/java/org/jboss/netty/example/discard/DiscardClientHandler.java @@ -24,7 +24,6 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelState; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; @@ -40,7 +39,6 @@ import org.jboss.netty.channel.WriteCompletionEvent; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class DiscardClientHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/discard/DiscardServerHandler.java b/src/main/java/org/jboss/netty/example/discard/DiscardServerHandler.java index a3a7c06ae4..67ec94682f 100644 --- a/src/main/java/org/jboss/netty/example/discard/DiscardServerHandler.java +++ b/src/main/java/org/jboss/netty/example/discard/DiscardServerHandler.java @@ -22,7 +22,6 @@ import java.util.logging.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -36,7 +35,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class DiscardServerHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/echo/EchoClientHandler.java b/src/main/java/org/jboss/netty/example/echo/EchoClientHandler.java index 10ad8227da..ebd60eb35c 100644 --- a/src/main/java/org/jboss/netty/example/echo/EchoClientHandler.java +++ b/src/main/java/org/jboss/netty/example/echo/EchoClientHandler.java @@ -22,7 +22,6 @@ import java.util.logging.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -38,7 +37,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class EchoClientHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/echo/EchoServerHandler.java b/src/main/java/org/jboss/netty/example/echo/EchoServerHandler.java index ee72e178e6..1a815bb1ae 100644 --- a/src/main/java/org/jboss/netty/example/echo/EchoServerHandler.java +++ b/src/main/java/org/jboss/netty/example/echo/EchoServerHandler.java @@ -21,7 +21,6 @@ import java.util.logging.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; @@ -34,7 +33,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class EchoServerHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/factorial/FactorialClientHandler.java b/src/main/java/org/jboss/netty/example/factorial/FactorialClientHandler.java index 4c43bd70e1..8c4d36e98c 100644 --- a/src/main/java/org/jboss/netty/example/factorial/FactorialClientHandler.java +++ b/src/main/java/org/jboss/netty/example/factorial/FactorialClientHandler.java @@ -26,7 +26,6 @@ import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -44,7 +43,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") // <-- HERE public class FactorialClientHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/factorial/FactorialServerHandler.java b/src/main/java/org/jboss/netty/example/factorial/FactorialServerHandler.java index a016cd6955..404b60a4d3 100644 --- a/src/main/java/org/jboss/netty/example/factorial/FactorialServerHandler.java +++ b/src/main/java/org/jboss/netty/example/factorial/FactorialServerHandler.java @@ -22,7 +22,6 @@ import java.util.logging.Logger; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -40,7 +39,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") // <-- HERE public class FactorialServerHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/factorial/NumberEncoder.java b/src/main/java/org/jboss/netty/example/factorial/NumberEncoder.java index 6f988d1896..cfd157539c 100644 --- a/src/main/java/org/jboss/netty/example/factorial/NumberEncoder.java +++ b/src/main/java/org/jboss/netty/example/factorial/NumberEncoder.java @@ -21,7 +21,6 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; /** @@ -34,7 +33,6 @@ import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; * @version $Rev$, $Date$ * */ -@ChannelPipelineCoverage("all") public class NumberEncoder extends OneToOneEncoder { @Override diff --git a/src/main/java/org/jboss/netty/example/http/file/HttpStaticFileServerHandler.java b/src/main/java/org/jboss/netty/example/http/file/HttpStaticFileServerHandler.java index 5d05e0af01..0b587df5d2 100644 --- a/src/main/java/org/jboss/netty/example/http/file/HttpStaticFileServerHandler.java +++ b/src/main/java/org/jboss/netty/example/http/file/HttpStaticFileServerHandler.java @@ -32,7 +32,6 @@ import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; @@ -48,7 +47,6 @@ import org.jboss.netty.util.CharsetUtil; * @author The Netty Project * @author Trustin Lee */ -@ChannelPipelineCoverage("one") public class HttpStaticFileServerHandler extends SimpleChannelUpstreamHandler { @Override diff --git a/src/main/java/org/jboss/netty/example/http/snoop/HttpRequestHandler.java b/src/main/java/org/jboss/netty/example/http/snoop/HttpRequestHandler.java index e82eb9ab3c..2f89f17610 100644 --- a/src/main/java/org/jboss/netty/example/http/snoop/HttpRequestHandler.java +++ b/src/main/java/org/jboss/netty/example/http/snoop/HttpRequestHandler.java @@ -30,7 +30,6 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; @@ -52,7 +51,6 @@ import org.jboss.netty.util.CharsetUtil; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") public class HttpRequestHandler extends SimpleChannelUpstreamHandler { private volatile HttpRequest request; diff --git a/src/main/java/org/jboss/netty/example/http/snoop/HttpResponseHandler.java b/src/main/java/org/jboss/netty/example/http/snoop/HttpResponseHandler.java index 246a3433dd..6e8ac779a2 100644 --- a/src/main/java/org/jboss/netty/example/http/snoop/HttpResponseHandler.java +++ b/src/main/java/org/jboss/netty/example/http/snoop/HttpResponseHandler.java @@ -17,7 +17,6 @@ package org.jboss.netty.example.http.snoop; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; import org.jboss.netty.handler.codec.http.HttpChunk; @@ -31,7 +30,6 @@ import org.jboss.netty.util.CharsetUtil; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") public class HttpResponseHandler extends SimpleChannelUpstreamHandler { private volatile boolean readingChunks; diff --git a/src/main/java/org/jboss/netty/example/http/websocket/WebSocketServerHandler.java b/src/main/java/org/jboss/netty/example/http/websocket/WebSocketServerHandler.java index b0d1be337f..0dc87f7c7b 100644 --- a/src/main/java/org/jboss/netty/example/http/websocket/WebSocketServerHandler.java +++ b/src/main/java/org/jboss/netty/example/http/websocket/WebSocketServerHandler.java @@ -28,7 +28,6 @@ import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; @@ -51,7 +50,6 @@ import org.jboss.netty.util.CharsetUtil; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") public class WebSocketServerHandler extends SimpleChannelUpstreamHandler { private static final String WEBSOCKET_PATH = "/websocket"; diff --git a/src/main/java/org/jboss/netty/example/local/LocalServerPipelineFactory.java b/src/main/java/org/jboss/netty/example/local/LocalServerPipelineFactory.java index 350cda3206..d3898843d1 100644 --- a/src/main/java/org/jboss/netty/example/local/LocalServerPipelineFactory.java +++ b/src/main/java/org/jboss/netty/example/local/LocalServerPipelineFactory.java @@ -21,7 +21,6 @@ import org.jboss.netty.channel.ChannelDownstreamHandler; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelUpstreamHandler; import org.jboss.netty.channel.Channels; @@ -53,7 +52,6 @@ public class LocalServerPipelineFactory implements ChannelPipelineFactory { return pipeline; } - @ChannelPipelineCoverage("all") static class EchoCloseServerHandler implements ChannelUpstreamHandler, ChannelDownstreamHandler { public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception { diff --git a/src/main/java/org/jboss/netty/example/localtime/LocalTimeClientHandler.java b/src/main/java/org/jboss/netty/example/localtime/LocalTimeClientHandler.java index 055e774829..e2e7109685 100644 --- a/src/main/java/org/jboss/netty/example/localtime/LocalTimeClientHandler.java +++ b/src/main/java/org/jboss/netty/example/localtime/LocalTimeClientHandler.java @@ -27,7 +27,6 @@ import java.util.logging.Logger; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -44,7 +43,6 @@ import org.jboss.netty.example.localtime.LocalTimeProtocol.Locations; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") public class LocalTimeClientHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/localtime/LocalTimeServerHandler.java b/src/main/java/org/jboss/netty/example/localtime/LocalTimeServerHandler.java index fc8d1189ff..261d709784 100644 --- a/src/main/java/org/jboss/netty/example/localtime/LocalTimeServerHandler.java +++ b/src/main/java/org/jboss/netty/example/localtime/LocalTimeServerHandler.java @@ -24,7 +24,6 @@ import java.util.logging.Logger; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -42,7 +41,6 @@ import org.jboss.netty.example.localtime.LocalTimeProtocol.Locations; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class LocalTimeServerHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/objectecho/ObjectEchoClientHandler.java b/src/main/java/org/jboss/netty/example/objectecho/ObjectEchoClientHandler.java index 50dde3282d..385964c167 100644 --- a/src/main/java/org/jboss/netty/example/objectecho/ObjectEchoClientHandler.java +++ b/src/main/java/org/jboss/netty/example/objectecho/ObjectEchoClientHandler.java @@ -23,7 +23,6 @@ import java.util.logging.Logger; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelState; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; @@ -40,7 +39,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class ObjectEchoClientHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/objectecho/ObjectEchoServerHandler.java b/src/main/java/org/jboss/netty/example/objectecho/ObjectEchoServerHandler.java index 39b4f43177..307adbd782 100644 --- a/src/main/java/org/jboss/netty/example/objectecho/ObjectEchoServerHandler.java +++ b/src/main/java/org/jboss/netty/example/objectecho/ObjectEchoServerHandler.java @@ -21,7 +21,6 @@ import java.util.logging.Logger; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelState; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; @@ -37,7 +36,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class ObjectEchoServerHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/proxy/HexDumpProxyInboundHandler.java b/src/main/java/org/jboss/netty/example/proxy/HexDumpProxyInboundHandler.java index db4ced7442..b34bedc544 100644 --- a/src/main/java/org/jboss/netty/example/proxy/HexDumpProxyInboundHandler.java +++ b/src/main/java/org/jboss/netty/example/proxy/HexDumpProxyInboundHandler.java @@ -24,7 +24,6 @@ import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -36,7 +35,6 @@ import org.jboss.netty.channel.socket.ClientSocketChannelFactory; * @author Trustin Lee * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") public class HexDumpProxyInboundHandler extends SimpleChannelUpstreamHandler { private final ClientSocketChannelFactory cf; @@ -102,7 +100,6 @@ public class HexDumpProxyInboundHandler extends SimpleChannelUpstreamHandler { closeOnFlush(e.getChannel()); } - @ChannelPipelineCoverage("one") private static class OutboundHandler extends SimpleChannelUpstreamHandler { private final Channel inboundChannel; diff --git a/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentClientHandler.java b/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentClientHandler.java index d96e8e7dc6..cab0c2652f 100644 --- a/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentClientHandler.java +++ b/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentClientHandler.java @@ -16,7 +16,6 @@ package org.jboss.netty.example.qotm; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; @@ -26,7 +25,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * @author Trustin Lee * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class QuoteOfTheMomentClientHandler extends SimpleChannelUpstreamHandler { @Override diff --git a/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentServerHandler.java b/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentServerHandler.java index c953832ea8..cf247ea68b 100644 --- a/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentServerHandler.java +++ b/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentServerHandler.java @@ -18,7 +18,6 @@ package org.jboss.netty.example.qotm; import java.util.Random; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; @@ -28,7 +27,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * @author Trustin Lee * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class QuoteOfTheMomentServerHandler extends SimpleChannelUpstreamHandler { private static final Random random = new Random(); diff --git a/src/main/java/org/jboss/netty/example/securechat/SecureChatClientHandler.java b/src/main/java/org/jboss/netty/example/securechat/SecureChatClientHandler.java index 0de6de6cb3..f9537ae258 100644 --- a/src/main/java/org/jboss/netty/example/securechat/SecureChatClientHandler.java +++ b/src/main/java/org/jboss/netty/example/securechat/SecureChatClientHandler.java @@ -20,7 +20,6 @@ import java.util.logging.Logger; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -35,7 +34,6 @@ import org.jboss.netty.handler.ssl.SslHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class SecureChatClientHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/securechat/SecureChatServerHandler.java b/src/main/java/org/jboss/netty/example/securechat/SecureChatServerHandler.java index 829fb6285d..fe94953554 100644 --- a/src/main/java/org/jboss/netty/example/securechat/SecureChatServerHandler.java +++ b/src/main/java/org/jboss/netty/example/securechat/SecureChatServerHandler.java @@ -24,7 +24,6 @@ import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -41,7 +40,6 @@ import org.jboss.netty.handler.ssl.SslHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class SecureChatServerHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/telnet/TelnetClientHandler.java b/src/main/java/org/jboss/netty/example/telnet/TelnetClientHandler.java index 86fe32e454..d5ee47fccb 100644 --- a/src/main/java/org/jboss/netty/example/telnet/TelnetClientHandler.java +++ b/src/main/java/org/jboss/netty/example/telnet/TelnetClientHandler.java @@ -20,7 +20,6 @@ import java.util.logging.Logger; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -34,7 +33,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class TelnetClientHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/telnet/TelnetServerHandler.java b/src/main/java/org/jboss/netty/example/telnet/TelnetServerHandler.java index af03c111af..17ab96909b 100644 --- a/src/main/java/org/jboss/netty/example/telnet/TelnetServerHandler.java +++ b/src/main/java/org/jboss/netty/example/telnet/TelnetServerHandler.java @@ -24,7 +24,6 @@ import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; @@ -38,7 +37,6 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("all") public class TelnetServerHandler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger( diff --git a/src/main/java/org/jboss/netty/example/uptime/UptimeClientHandler.java b/src/main/java/org/jboss/netty/example/uptime/UptimeClientHandler.java index d84ad53aa1..7ee80c3613 100644 --- a/src/main/java/org/jboss/netty/example/uptime/UptimeClientHandler.java +++ b/src/main/java/org/jboss/netty/example/uptime/UptimeClientHandler.java @@ -21,7 +21,6 @@ import java.util.concurrent.TimeUnit; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; @@ -38,7 +37,6 @@ import org.jboss.netty.util.TimerTask; * * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") public class UptimeClientHandler extends SimpleChannelUpstreamHandler { final ClientBootstrap bootstrap; diff --git a/src/main/java/org/jboss/netty/handler/codec/base64/Base64Decoder.java b/src/main/java/org/jboss/netty/handler/codec/base64/Base64Decoder.java index 556fc9d9df..6cc5228003 100644 --- a/src/main/java/org/jboss/netty/handler/codec/base64/Base64Decoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/base64/Base64Decoder.java @@ -20,7 +20,7 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineCoverage; +import org.jboss.netty.channel.ChannelHandler.Sharable; import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; import org.jboss.netty.handler.codec.frame.Delimiters; import org.jboss.netty.handler.codec.frame.FrameDecoder; @@ -50,7 +50,7 @@ import org.jboss.netty.util.CharsetUtil; * * @apiviz.uses org.jboss.netty.handler.codec.base64.Base64 */ -@ChannelPipelineCoverage("all") +@Sharable public class Base64Decoder extends OneToOneDecoder { private final Base64Dialect dialect; diff --git a/src/main/java/org/jboss/netty/handler/codec/base64/Base64Encoder.java b/src/main/java/org/jboss/netty/handler/codec/base64/Base64Encoder.java index c0098df72a..954822606d 100644 --- a/src/main/java/org/jboss/netty/handler/codec/base64/Base64Encoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/base64/Base64Encoder.java @@ -19,7 +19,7 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineCoverage; +import org.jboss.netty.channel.ChannelHandler.Sharable; import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; import org.jboss.netty.handler.codec.frame.Delimiters; import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; @@ -44,7 +44,7 @@ import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; * * @apiviz.uses org.jboss.netty.handler.codec.base64.Base64 */ -@ChannelPipelineCoverage("all") +@Sharable public class Base64Encoder extends OneToOneEncoder { private final boolean breakLines; diff --git a/src/main/java/org/jboss/netty/handler/codec/compression/ZlibDecoder.java b/src/main/java/org/jboss/netty/handler/codec/compression/ZlibDecoder.java index 4c3748855f..f326522478 100644 --- a/src/main/java/org/jboss/netty/handler/codec/compression/ZlibDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/compression/ZlibDecoder.java @@ -19,7 +19,6 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; import org.jboss.netty.util.internal.jzlib.JZlib; import org.jboss.netty.util.internal.jzlib.ZStream; @@ -32,7 +31,6 @@ import org.jboss.netty.util.internal.jzlib.ZStream; * @author Trustin Lee * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") public class ZlibDecoder extends OneToOneDecoder { private final ZStream z = new ZStream(); diff --git a/src/main/java/org/jboss/netty/handler/codec/compression/ZlibEncoder.java b/src/main/java/org/jboss/netty/handler/codec/compression/ZlibEncoder.java index 04868cefcb..08239fe17e 100644 --- a/src/main/java/org/jboss/netty/handler/codec/compression/ZlibEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/compression/ZlibEncoder.java @@ -24,7 +24,6 @@ import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.LifeCycleAwareChannelHandler; @@ -40,7 +39,6 @@ import org.jboss.netty.util.internal.jzlib.ZStream; * @author Trustin Lee * @version $Rev$, $Date$ */ -@ChannelPipelineCoverage("one") public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChannelHandler { private static final byte[] EMPTY_ARRAY = new byte[0]; diff --git a/src/main/java/org/jboss/netty/handler/codec/embedder/AbstractCodecEmbedder.java b/src/main/java/org/jboss/netty/handler/codec/embedder/AbstractCodecEmbedder.java index 6c9039b347..56dbe8c7b0 100644 --- a/src/main/java/org/jboss/netty/handler/codec/embedder/AbstractCodecEmbedder.java +++ b/src/main/java/org/jboss/netty/handler/codec/embedder/AbstractCodecEmbedder.java @@ -28,7 +28,6 @@ import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelPipelineException; import org.jboss.netty.channel.ChannelSink; import org.jboss.netty.channel.ChannelUpstreamHandler; @@ -181,7 +180,6 @@ abstract class AbstractCodecEmbedder
* // An example that sends a ping message when there is no traffic * // (either inbound or outbound) for 30 seconds. - * ChannelPipeline p = ...; - * Timer timer = new HashedWheelTimer(); - * p.addLast("timeout", new IdleStateHandler(timer, 30, 30, 0)); - * p.addLast("handler", new MyHandler()); + * + * public class MyPipelineFactory implements ChannelPipelineFactory { + * + * public MyPipelineFactory(Timer timer) { + * this.timer = timer; + * } + * + * public ChannelPipeline getPipeline() { + * return Channels.pipeline( + * new IdleStateHandler(timer, 30, 30, 0), + * new MyHandler()); + * } + * } * * // Handler should handle the IdleStateEvent triggered by IdleStateHandler. * public class MyHandler extends IdleStateAwareChannelHandler { @@ -77,6 +85,11 @@ import org.jboss.netty.util.TimerTask; * } * } * + * ServerBootstrap bootstrap = ...; + * Timer timer = new HashedWheelTimer(); + * ... + * bootstrap.setPipelineFactory(new MyPipelineFactory(timer)); + * ... * // To shut down, call {@link #releaseExternalResources()} or {@link Timer#stop()}. ** @@ -91,7 +104,6 @@ import org.jboss.netty.util.TimerTask; * @apiviz.uses org.jboss.netty.util.HashedWheelTimer * @apiviz.has org.jboss.netty.handler.timeout.IdleStateEvent oneway - - triggers */ -@ChannelPipelineCoverage("one") public class IdleStateHandler extends SimpleChannelUpstreamHandler implements LifeCycleAwareChannelHandler, ExternalResourceReleasable { diff --git a/src/main/java/org/jboss/netty/handler/timeout/ReadTimeoutHandler.java b/src/main/java/org/jboss/netty/handler/timeout/ReadTimeoutHandler.java index c127109793..5997bd3ecf 100644 --- a/src/main/java/org/jboss/netty/handler/timeout/ReadTimeoutHandler.java +++ b/src/main/java/org/jboss/netty/handler/timeout/ReadTimeoutHandler.java @@ -20,7 +20,6 @@ import static org.jboss.netty.channel.Channels.*; import java.util.concurrent.TimeUnit; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.LifeCycleAwareChannelHandler; @@ -37,14 +36,26 @@ import org.jboss.netty.util.TimerTask; * period of time. * *
- * // An example configuration that implements 30-second read timeout: - * ChannelPipeline p = ...; - * Timer timer = new HashedWheelTimer(); - * p.addLast("timeout", new ReadTimeoutHandler(timer, 30)); - * p.addLast("handler", new MyHandler()); + * public class MyPipelineFactory implements ChannelPipelineFactory { * + * public MyPipelineFactory(Timer timer) { + * this.timer = timer; + * } + * + * public ChannelPipeline getPipeline() { + * // An example configuration that implements 30-second read timeout: + * return Channels.pipeline( + * new ReadTimeoutHandler(timer, 30), + * new MyHandler()); + * } + * } + * + * ServerBootstrap bootstrap = ...; + * Timer timer = new HashedWheelTimer(); + * ... + * bootstrap.setPipelineFactory(new MyPipelineFactory(timer)); + * ... * // To shut down, call {@link #releaseExternalResources()} or {@link Timer#stop()}. - ** * @author The Netty Project * @author Trustin Lee @@ -57,7 +68,6 @@ import org.jboss.netty.util.TimerTask; * @apiviz.uses org.jboss.netty.util.HashedWheelTimer * @apiviz.has org.jboss.netty.handler.timeout.TimeoutException oneway - - raises */ -@ChannelPipelineCoverage("one") public class ReadTimeoutHandler extends SimpleChannelUpstreamHandler implements LifeCycleAwareChannelHandler, ExternalResourceReleasable { diff --git a/src/main/java/org/jboss/netty/handler/timeout/WriteTimeoutHandler.java b/src/main/java/org/jboss/netty/handler/timeout/WriteTimeoutHandler.java index 91fac2fb50..79ea7d7775 100644 --- a/src/main/java/org/jboss/netty/handler/timeout/WriteTimeoutHandler.java +++ b/src/main/java/org/jboss/netty/handler/timeout/WriteTimeoutHandler.java @@ -22,10 +22,10 @@ import java.util.concurrent.TimeUnit; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelDownstreamHandler; +import org.jboss.netty.channel.ChannelHandler.Sharable; import org.jboss.netty.util.ExternalResourceReleasable; import org.jboss.netty.util.HashedWheelTimer; import org.jboss.netty.util.Timeout; @@ -37,12 +37,25 @@ import org.jboss.netty.util.TimerTask; * certain period of time. * *
- * // An example configuration that implements 30-second write timeout: - * ChannelPipeline p = ...; - * Timer timer = new HashedWheelTimer(); - * p.addLast("timeout", new WriteTimeoutHandler(timer, 30)); - * p.addLast("handler", new MyHandler()); + * public class MyPipelineFactory implements ChannelPipelineFactory { * + * public MyPipelineFactory(Timer timer) { + * this.timer = timer; + * } + * + * public ChannelPipeline getPipeline() { + * // An example configuration that implements 30-second write timeout: + * return Channels.pipeline( + * new WriteTimeoutHandler(timer, 30), + * new MyHandler()); + * } + * } + * + * ServerBootstrap bootstrap = ...; + * Timer timer = new HashedWheelTimer(); + * ... + * bootstrap.setPipelineFactory(new MyPipelineFactory(timer)); + * ... * // To shut down, call {@link #releaseExternalResources()} or {@link Timer#stop()}. ** @@ -57,7 +70,7 @@ import org.jboss.netty.util.TimerTask; * @apiviz.uses org.jboss.netty.util.HashedWheelTimer * @apiviz.has org.jboss.netty.handler.timeout.TimeoutException oneway - - raises */ -@ChannelPipelineCoverage("all") +@Sharable public class WriteTimeoutHandler extends SimpleChannelDownstreamHandler implements ExternalResourceReleasable {