New and noteworthy in 5.0
This document walks you through the list of notable changes and new features in the major Netty release (since 4.1) to give you an idea to port your application to the new version.
Unlike the changes between 3.x and 4.0, 5.0 did not change a lot although it made quite a bit of breakthrough in its design simplicity. We tried to make the transition from 4.x to 5.0 as smooth as possible, but please let us know if you encounter any issues during migration.
Simplified handler type hierarchy
ChannelDuplexHandlerAdapter have been deprecated and replaced by
Because it is now impossible to tell if a handler is an inbound handler or an outbound handler,
CombinedChannelDuplexHandler has been replaced by
For more information about this change, please refer to the pull request #1999.
Even more flexible thread model
Starting with version 5.0 an
EventLoop does no longer use threads directly but instead makes use of an
Executor abstraction. That is, it takes an
Executor object as a parameter in its constructor and instead of polling for I/O
events in an endless loop each iteration is now a task that is submitted to this
If not specified else, the
Executor used by default is a
ForkJoinPool has the nice property of using thread-local queues. That is, a task submitted to a
Thread A is very likely to be executed by
Thread A again. This should provide
EventLoops with a high level of thread affinity.
Furthermore, developers may also provide their own
Executor (aka thread pool) and take over the scheduling of the
EventLoops. One scenario where this can prove useful is when Netty is used as a part of a large scale software system. Let's say this system already uses a thread pool with a high level of parallelism to optimally perform all its tasks. Netty 4.x would simply spawn its own threads and completely ignore the fact that it's part of a larger system. Starting with Netty 5.0, developers can run Netty and the rest of the system in the same thread pool and potentially improve performance by applying better scheduling strategies and through less scheduling overhead (due to fewer threads). For a detailed discussion of this change please have a look at GitHub issue 2250.
It shall be mentioned, that this change does not in any way affect the way
ChannelHandlers are developed. From a developer's point of view, the only thing that changes is that it's no longer guaranteed that a
ChannelHandler will always be executed by the same thread. It is, however, guaranteed that it will never be executed by two or more threads at the same time. Furthermore, Netty will also take care of any memory visibility issues that might occur. So there's no need to worry about thread-safety and
volatile variables within a
An implication of this change is that
EpollEventLoopGroup do no longer take
ThreadFactory objects as constructor arguments. The constructors of these classes have been updated to take
ExecutorFactory objects instead.
Originally introduced in Netty 4.0, the behaviour of
Channel.deregister(...) was updated in version 5.0 to be in line
with Netty's thread model.
It's now ensured that all tasks submitted to an
EventLoop from within a
ChannelHandler will have been executed by that
EventLoop before the
Channel is actually deregistered. However,
Channel.deregister(...) remains a non blocking operation, so one has to wait for the returned
ChannelFuture to succeed before it's safe to register the
Channel with another
After having called
Channel.deregister(...) any attempt to submit a new task (
Callable) to the
EventLoop from within a
ChannelHandler will trigger a
RejectedExecutionException. Once the
Channel is registered with another
EventLoop again, everything will work as usual.
A task submitted from within
ChannelHandler via any of the
EventLoop.schedule*(...) methods will stop execution
Channel was deregistered from its
EventLoop. The tasks are automatically moved to the new
EventLoop and will resume execution after the
Channel is registered again. This limitation only affects tasks
that are scheduled to execute while the
Channel is in a deregistered state. Tasks who's delay/period is long enough
will not be affected.
Even though it's not recommended, it is possible to overcome the above restrictions. Netty 5.0 introduces a new method
EventLoop.unwrap() that returns the original
EventLoop that does not perform any sanity checks. More precisely, when submitting tasks to or scheduling tasks with an "unwrapped"
EventLoop, it cannot be assured that these tasks will not be executed concurrently and scheduled tasks will also not be moved between