Skip to content

Fall back to plain SO_KEEPALIVE when jdk.net module is absent - #3864

Open
meteaksoyy wants to merge 1 commit into
redis:mainfrom
meteaksoyy:fix-extended-socket-options-fallback
Open

Fall back to plain SO_KEEPALIVE when jdk.net module is absent#3864
meteaksoyy wants to merge 1 commit into
redis:mainfrom
meteaksoyy:fix-extended-socket-options-fallback

Conversation

@meteaksoyy

@meteaksoyy meteaksoyy commented Jul 24, 2026

Copy link
Copy Markdown

ExtendedKeepAliveSupport.ExtendedNioSocketOptions referenced jdk.net.ExtendedSocketOptions through a class literal, so on runtimes without the jdk.net module (for example custom jlink images) class initialization failed with NoClassDefFoundError and crashed application startup. Since #3669 made extended keep-alive the default, this happens for every affected application.

The class is now resolved via Class.forName, so a missing module results in a catchable ClassNotFoundException and Lettuce degrades to plain SO_KEEPALIVE, restoring the pre-7.5.0 behavior. LinkageError is caught alongside ReflectiveOperationException to cover partially available modules, and unavailability is logged at debug level.

New ExtendedKeepAliveSupportUnitTests includes a reproducer that loads the class in a classloader refusing jdk.net.*, simulating a runtime image without the module. It fails with the reported NoClassDefFoundError against the previous code and passes with this change.

Fixes #3862

Make sure that:

  • You have read the contribution guidelines.
  • You have created a feature request first to discuss your contribution intent. Please reference the feature request ticket number in the pull request.
  • You applied code formatting rules using the mvn formatter:format target. Don't submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.

Note

Low Risk
Narrow change to optional NIO keep-alive discovery with graceful degradation; behavior on full JDKs unchanged when jdk.net is present.

Overview
Fixes startup crashes on custom jlink (or other) runtimes that omit the jdk.net module, where ExtendedNioSocketOptions used to pull in jdk.net.ExtendedSocketOptions via a compile-time reference and could throw NoClassDefFoundError during static init.

ExtendedNioSocketOptions now loads jdk.net.ExtendedSocketOptions with Class.forName, drops the direct import, and treats ReflectiveOperationException and LinkageError as "extended options unavailable" (debug log, null socket options). isSupported() / isAvailable() then report false and Lettuce falls back to plain SO_KEEPALIVE instead of failing startup.

Adds ExtendedKeepAliveSupportUnitTests: standard JDK 11+ availability, isSupported() must not throw, and a jdk.net.*-blocking classloader reproducer that expects isAvailable() == false without NoClassDefFoundError.

Reviewed by Cursor Bugbot for commit 162f4be. Bugbot is set up for automated code reviews on this repo. Configure here.

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.

NoClassDefFoundError: jdk/net/ExtendedSocketOptions crashes application startup instead of falling back to plain SO_KEEPALIVE

1 participant