Skip to content

Bump Netty to 4.2.2 #6205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Bump Netty to 4.2.2 #6205

wants to merge 7 commits into from

Conversation

davidh44
Copy link
Contributor

@davidh44 davidh44 commented Jun 24, 2025

Motivation and Context

Bump Netty to 4.2.2 Final
https://github.com/netty/netty/wiki/Netty-4.2-Migration-Guide

Modifications

  • Replace netty-codec with netty-codec-base
  • Replace NioEventLoopGroup with MultiThreadIoEventLoopGroup
  • Bump netty-open-ssl-version to 2.0.72.Final
  • Replace bcpkix-jdk15on with bcpkix-jdk18on and bump to 1.80
  • Add overload for SdkEventLoopGroup.create() to allow passing in socket and datagram channels

Testing

Integ tests passed

Ran sdk-benchmarks for Netty with both 4.1.118.Final and 4.2.2.Final

4.1.118

Benchmark                                     (sslProviderValue)   Mode  Cnt     Score     Error  Units
NettyHttpClientH2Benchmark.concurrentApiCall                 jdk  thrpt    5  5924.208 ± 199.451  ops/s
NettyHttpClientH2Benchmark.concurrentApiCall             openssl  thrpt    5  6946.568 ± 303.472  ops/s
NettyHttpClientH2Benchmark.sequentialApiCall                 jdk  thrpt    5  2323.924 ± 118.273  ops/s
NettyHttpClientH2Benchmark.sequentialApiCall             openssl  thrpt    5  2386.245 ± 209.562  ops/s

4.2.2

Benchmark                                     (sslProviderValue)   Mode  Cnt     Score     Error  Units
NettyHttpClientH2Benchmark.concurrentApiCall                 jdk  thrpt    5  6627.154 ± 194.091  ops/s
NettyHttpClientH2Benchmark.concurrentApiCall             openssl  thrpt    5  7769.429 ± 283.274  ops/s
NettyHttpClientH2Benchmark.sequentialApiCall                 jdk  thrpt    5  2163.251 ±  93.223  ops/s
NettyHttpClientH2Benchmark.sequentialApiCall             openssl  thrpt    5  2338.593 ±  98.592  ops/s

With the version bump to 4.2.2:
For concurrent calls, we see 12% improvement for both JDK and OpenSSL providers.
For sequential calls, we see 7% drop for JDK provider, and 2% drop for OpenSSL provider

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the CONTRIBUTING document
  • Local run of mvn install succeeds
  • My code follows the code style of this project
  • My change requires a change to the Javadoc documentation
  • I have updated the Javadoc documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed
  • I have added a changelog entry. Adding a new entry must be accomplished by running the scripts/new-change script and following the instructions. Commit the new file created by the script in .changes/next-release with your changes.
  • My change is to implement 1.11 parity feature and I have updated LaunchChangelog

License

  • I confirm that this pull request can be released under the Apache 2 license

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
B Maintainability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@@ -336,7 +336,6 @@ public static SslHandler newSslHandler(SslContext sslContext, ByteBufAllocator a
*/
private static void configureSslEngine(SSLEngine sslEngine) {
SSLParameters sslParameters = sslEngine.getSSLParameters();
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidh44 davidh44 marked this pull request as ready for review June 25, 2025 23:49
@davidh44 davidh44 requested a review from a team as a code owner June 25, 2025 23:49
@@ -0,0 +1,6 @@
{
"type": "feature",
"category": "AWS SDK for Java v2",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be "Netty NIO HTTP Client"

@@ -116,7 +116,7 @@
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec</artifactId>
<artifactId>netty-codec-base</artifactId>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did Netty deprecate netty-codec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The netty-codec module has been split into a number of different sub-modules, which the netty-codec module then depends on. In other words, netty-codec is now multiple jar files instead of one.

Comment on lines 158 to 163
* If {@link MultiThreadIoEventLoopGroup} is passed in, {@link NioSocketChannel} and {@link NioDatagramChannel} will be
* resolved, regardless of the transport {@link IoHandlerFactory} set on the {@link MultiThreadIoEventLoopGroup}. This is
* because it is not possible to determine the type of transport factory from a given {@link MultiThreadIoEventLoopGroup}.
* <p>
* To use a {@link MultiThreadIoEventLoopGroup} with a non-Nio transport factory, use
* {@link #create(EventLoopGroup, ChannelFactory, ChannelFactory)}, specifying the socket and datagram channels.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way this is worded is hard to follow. From what I understand, if the customer calls this with a MultiThreadIoEventLoopGroup (and not one of its subclasses like NioEventLoopGroup), then the SDK will disregard the IoHandler the event loop group was constructed with when choosing the factory, and always assume NioSocketChannel::new.

And if they want to ensure that specific factories are used, to use one of the other overloads?

What happens if there is a mismatch in the IoHandlerFactory and the resolved SocketFactory (e.g. epoll vs NIO)? Is there a clear error message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if they want to ensure that specific factories are used, to use one of the other overloads?

Correct, I'll try to make the wording more clear

What happens if there is a mismatch in the IoHandlerFactory and the resolved SocketFactory (e.g. epoll vs NIO)? Is there a clear error message?

Tested this:

        SdkEventLoopGroup sdkEventLoopGroup =
            SdkEventLoopGroup.create(new MultiThreadIoEventLoopGroup(KQueueIoHandler.newFactory()),
                                     NioSocketChannel::new,
                                     NioDatagramChannel::new);

        SdkAsyncHttpClient netty = NettyNioAsyncHttpClient.builder()
                                                          .eventLoopGroup(sdkEventLoopGroup)
                                                          .build();
        S3AsyncClient asyncClient = S3AsyncClient.builder()
                                                 .region(DEFAULT_REGION)
                                                 .credentialsProvider(CREDENTIALS_PROVIDER_CHAIN)
                                                 .httpClient(netty)

                                                 .build();
        asyncClient.headObject(c -> c.bucket(BUCKET).key(ASYNC_KEY)).join();

Got error message:

java.util.concurrent.CompletionException: software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: incompatible event loop type: io.netty.channel.SingleThreadIoEventLoop (SDK Attempt Count: 1)
...
Caused by: java.lang.IllegalStateException: incompatible event loop type: io.netty.channel.SingleThreadIoEventLoop
	at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:332)
	at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:119)
	at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:113)
	at io.netty.channel.MultithreadEventLoopGroup.register(MultithreadEventLoopGroup.java:86)
	at software.amazon.awssdk.http.nio.netty.internal.DelegatingEventLoopGroup.register(DelegatingEventLoopGroup.java:173)
	at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:339)
	at io.netty.bootstrap.Bootstrap.doResolveAndConnect(Bootstrap.java:164)
	at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:125)

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
43.4% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants