Netty 4.2 Migration Guide
Netty 4.2 is largely backwards compatible with Netty 4.1, but there are a few choice compatibility breakages to be aware of, and a couple of new features worth knowing about.
From our (the Netty team) perspective, one of the biggest changes is that we are changing the minimum Java version requirement from Java 6 to Java 8. This upgrade is a big quality-of-life improvement for us, but it likely has no impact on anyone else because there are almost no regularly maintained Java projects left that still use Java versions older than Java 8.
These are the most important compatibility breakages. The Netty team has done extensive validation testing of 4.2 in a number of large and high-profile projects, and these are the things that integrators are most likely to run into when upgrading their Netty dependencies from 4.1 to 4.2:
The SslContextBuilder.endpointIdentificationAlgorithm
setting is now set to HTTPS
by default, where in 4.1 it was null
by default. Not doing hostname verification is obsolete and insecure practice from a more innocent time, that we haven't been able to change until now since suddenly enabling it could potentially break many systems.
This default can be overridden with a system property, to restore the Netty 4.1 behavior:
io.netty.handler.ssl.defaultEndpointVerificationAlgorithm=NONE
The purpose of this override is to aid systems with the Netty 4.2 migration. Systems that intentionally wish to disable endpoint identification should do so through the SslContextBuilder
option.
adaptive
memory allocator is now the default.
In Netty 4.1 the adaptive
memory allocator was experimental. We have now made it the new default instead of the pooled
allocator.
We believe that most workloads will observe reduced memory usage, with performance that is on par or slightly better than the pooled allocator. The adaptive allocator automatically tunes itself to perform well for the observed workload. It was also designed from the start to work well with virtual threads.
However, every application use their allocator in different ways, and stress them differently, so it is expected that the adaptive allocator will perform worse for some. Integrators who wish to keep using the pooled allocator like they did in Netty 4.1, can change the default allocator by setting this system property:
io.netty.allocator.type=pooled
We have updated our (still optional) BouncyCastle dependency. This is a breaking change because of how BouncyCastle versions their artifacts.
Our BouncyCastle dependencies have all changed from their *-jdk15on
variants to their *-jdk18on
variants.
This means that if you, for instance, are depending on both Netty and bcprov-jdk15on
, then you will have to change which BouncyCastle artifact you depend on as part of your Netty 4.2 migration.
We have also upgraded the version we depend on from 1.69 to 1.80, which itself introduces compatibility breakages in their API.
netty-incubator-transport-io_uring
module is no longer supported.
In Netty 4.2 we have graduated the io_uring transport from incubator, to a fully supported first-class transport module.
As part of this work, we have made numerous refactorings to the Netty transport internals that render the incubator version entirely incompatible. The good news is that netty-transport-native-io_uring
is a much superior implementation thanks to these refactorings.
Integrators are encouraged to stop using the incubator module, and instead move to Netty 4.2 for its superior io_uring integration. Doing so will unfortunately require code changes. The following are things to watch out for:
- The package name changes from
io.netty.incubator.channel.uring
toio.netty.channel.uring
. - Class names are now prefixed
IoUring
instead ofIOUring
(note the lower-case ‘o’). - A number of io_uring channel options have changed.
-
IOUringEventLoopGroup
does not exist anymore and is superseded byMultiThreadIoEventLoopGroup
andIoUringIoHandler
. - Usage of io_uring now requires Java9+.
Netty 4.2 also includes a number of compatibility breakages that are less likely to cause problems, but needs to be mentioned regardless.
- The
protobuf-java
dependency has received a major version bump from 2.6.1 to 3.25.5. - The
netty-codec
module has been split into a number of different sub-modules, which thenetty-codec
module then depends on. In other words,netty-codec
is now multiple jar files instead of one. - We have dropped support for obsolete WebSocket draft specifications.
- Dropped support for Jetty alpn/npn as ALPN is supported out of the box when using Java8.
- The pipeline call-stack has been flattened, to reduce stack depths when processing messages through the pipeline. This may cause changes in behavior when messages are processed through the pipeline while the pipeline is concurrently modified, or when the pipeline makes use of child-executors.
- The minimum required GLibC version is bumped from 2.12 (May 2010, e.g. CentOS 6) to 2.17 (December 2012, e.g. CentOS 7).
- We are no longer testing our tcnative dynamic-linked OpenSSL integration with OpenSSL 1.0.1e (2013), and are now instead testing with OpenSSL 1.0.2k (2017).
- Switched from automatic to real modules for JPMS.
The complete and exhaustive list of API breakages has been compiled by RevAPI: https://github.com/netty/netty/blob/3ca17a96cf84cbcb08776d3731b222b82814ead7/pom.xml#L1271-L7794
Netty 4.2 introduces some new APIs, and deprecates some old APIs. As part of your migration to Netty 4.2, we encourage you to look through your code base for opportunities to clean up any use of deprecated APIs.
✅ IoHandlerFactories for EventLoopGroups
All transport-specific event loop groups, such as NioEventLoopGroup
, have been deprecated.
Integrators should now instead pass a transport-specific IoHandlerFactory
to a MultiThreadedEventLoopGroup
constructor.
For example, stop doing this
EventLoopGroup group = new NioEventLoopGroup(); // ❌
and instead start doing this
EventLoopGroup group = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory()); // ✅
There is a static newFactory
method for each of our transports:
NioIoHandler.newFactory()
EpollIoHandler.newFactory()
KQueueIoHandler.newFactory()
IoUringIoHandler.newFactory()
LocalIoHandler.newFactory()
Note that you must still configure the relevant channel or channel factory in your Bootstrap
or ServerBootstrap
instances.
✅ Extensibility of MultiThreadIoEventLoopGroup
and SingleThreadIoEventLoop
The MultiThreadIoEventLoopGroup
and SingleThreadIoEventLoop
classes provide various methods that can be overridden by the user, and provide the ability to:
- Get a count of registered channels / handles
- Understand how long the IO processing vs task processing took
- Get how many channels / handles were processed per loop run
- Customize / decorate promises
Furthermore, it is now possible to register other things than Channels (as long as the correct IoHandle
type is implemented), which provides a lot of possibilites to re-use netty components and also add support for other IoHandle
implementations which does not exists as of today. For example, this could be used to implement file IO with io_uring.
✅ Use netty-pkitesting instead of SelfSignedCertificate
Netty 4.1 includes a SelfSignedCertificate
class, which we use for testing our TLS implementation.
This was not intended to be used as widely as it has ended up, and it suffers from a number of API decisions that make it a poor fit as a general purpose PKI and TLS testing tool.
In Netty 4.2 we are introducing a new module, netty-pkitesting
, which includes a CertificateBuilder
class.
The CertificateBuilder
is designed to allow integrators to test all sorts of PKI and TLS scenarios.
You can make self-signed certificates like before, or you can make proper CA, issuer, leaf certificate chains.
The CertificateBuilder
produces X509Bundle
objects, which contain both certificate chains and the corresponding private key, and the bundles are created entirely in-memory without writing any files.
If you need files for certificates, keys, or key stores, then the bundle objects include a number of convenient methods for creating temporary files for these.
The netty-pkitesting
module also includes a simple Certificate Revocation List server, so you can test scenarios where certificates are revoked.