Skip to content

Conversation

@ChrisHegarty
Copy link
Contributor

A NIO socket channel supports setting and retrieving a set of socket
options. A socket channel supports a specified set of standard socket
options, e.g. SO_RCVBUF, as well as optional implementation specific
extended options. The network socket channels in the JDK support,
among others, the TCP_KEEPIDLE, TCP_KEEPINTERVAL, and
TCP_KEEPCOUNT extended socket options (on certain platforms). These
extended socket options are only available when their defining module,
jdk.net, is present, and also when defined to the bootstrap class
loader - the socket channel implementation in java.base uses
its class loader (the bootstrap class loader) to indirectly initialize
jdk.net.ExtendedSocketOptions. Therefore, the jdk.net module must be
in the same class loader - the bootstrap class loader - for the extended
socket options to be available/supported **.

The transport-netty4 component sets a number of extended socket options
on its network channels. Specifically, the TCP_KEEPIDLE,
TCP_KEEPINTERVAL, and TCP_KEEPCOUNT socket options. The code
responsible for this uses reflection with a silent fallback if the
options are not available, see o.e.transport.netty4.NetUtils. The use
of reflection is because of the desire to compile and run on JDK 8 when
initially added. This is no longer a requirement, since the minimal
runtime version is now JDK 17 and the extended socket options are
available since JDK 11.

With the move to Java modules, only the explicitly required modules or
modules resolved during service binding, are resolved from the JDK. The
jdk.net module is not currently resolved, since the extended socket
options are not directly used by any code defined by the system class
loader. Therefore the extended socket options are not available /
supported by the NIO socket channels in the runtime.

The transport-netty4 component, and its dependencies, are defined as
modules by a module layer that is a child of the boot layer. The code in
the transport-netty4 component refers to the socket options and attempts
to set them on a socket channel. While this is all fine and as it should
be, it will not succeed unless the socket channel implementation
supports the extended socket options, which requires the jdk.net
module to be resolved in the boot module layer (and loaded by the
bootstrap class loader).

Finally, the solution is to simply resolve the jdk.net module in the
boot layer. We do this by adding the --add-modules=jdk.net option,
rather than an explicit requires directive in the server module-info,
since no code in server uses the extended socket options. Additionally,
the transport-netty4 module-info has a requires directive added to
ensure that the jdk.net module is present. This directive doesn't
ensure that jdk.net is in the right module layer, but should be
sufficient for now, and will allow future refactorings in NetUtils to
replace the use of reflective access to the socket options with static
access.

Note: I'm still considering if or how best a test could be added to
assert this, but really once NetUtils is refactored that should be
sufficient.

closes #88897

**

$ cat SupportedOptions.java

import java.net.SocketOption;
import java.nio.channels.SocketChannel;
public class SupportedOptions {
    public static void main(String... args) throws Exception {
        System.out.println(SocketChannel.open().supportedOptions().stream().map(SocketOption::toString).sorted().toList());
    }
}
$ java SupportedOptions
[IP_TOS, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_RCVBUF, SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, TCP_KEEPCOUNT, TCP_KEEPIDLE, TCP_KEEPINTERVAL, TCP_NODELAY]
$ java --limit-modules=java.base SupportedOptions
[IP_TOS, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_RCVBUF, SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, TCP_NODELAY]

@ChrisHegarty ChrisHegarty added >bug Team:Core/Infra Meta label for core/infra team Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. labels Jul 29, 2022
@ChrisHegarty ChrisHegarty self-assigned this Jul 29, 2022
@elasticsearchmachine elasticsearchmachine added v8.5.0 needs:triage Requires assignment of a team area label and removed Team:Core/Infra Meta label for core/infra team Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. labels Jul 29, 2022
@DaveCTurner
Copy link
Contributor

DaveCTurner commented Jul 29, 2022

Can we drop the use of reflection in NetUtils at the same time?

(FWIW #88929 removes the mention of JDKs before JDK11 from the relevant docs)

@ChrisHegarty ChrisHegarty added the auto-backport Automatically create backport pull requests when merged label Jul 29, 2022
@DaveCTurner DaveCTurner added :Distributed Coordination/Network Http and internode communication implementations and removed auto-backport Automatically create backport pull requests when merged labels Jul 29, 2022
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-distributed (Team:Distributed)

@elasticsearchmachine elasticsearchmachine added Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. and removed needs:triage Requires assignment of a team area label labels Jul 29, 2022
@elasticsearchmachine
Copy link
Collaborator

Hi @ChrisHegarty, I've created a changelog YAML for you.

@ChrisHegarty
Copy link
Contributor Author

Can we drop the use of reflection in NetUtils at the same time?

Yes. I wanted to keep the changes as small as possible, but let me see how the refactoring looks.

@henningandersen
Copy link
Contributor

Can we drop the use of reflection in NetUtils at the same time?

I'd also prefer that. At a minimum we should change getExtendedSocketOptionOrNull to do:

            return (SocketOption<T>) jdk.net.ExtendedSocketOptions.class.getField(fieldName).get(null);

instead, since this was where the error originated. But we might as well go all in here. Happy to help out on this.

@ChrisHegarty
Copy link
Contributor Author

ChrisHegarty commented Jul 29, 2022

The use of reflection has been removed. There is a little indirection still, through accessors to the extended socket options, so as to narrow the suppression of the forbidden non-portable ExtendedSocketOptions type. In reality, while support for extended socket options is platform and implementation specific, all downstream distributions of OpenJDK have the ExtendedSocketOptions type defined.

@ChrisHegarty ChrisHegarty added the test-windows Trigger CI checks on Windows label Jul 29, 2022
Copy link
Contributor

@henningandersen henningandersen left a comment

Choose a reason for hiding this comment

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

LGTM, but I'd like David or Ryan to also review.

@ChrisHegarty ChrisHegarty added the auto-backport Automatically create backport pull requests when merged label Jul 29, 2022
Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@DaveCTurner DaveCTurner left a comment

Choose a reason for hiding this comment

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

LGTM3

@ChrisHegarty
Copy link
Contributor Author

Thanks for the reviews. I'm going to merge only after a full clean CI run on all platforms. And will then proceed to backport to 8.4, and 8.3.x.

@ChrisHegarty
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/packaging-tests-unix-sample

@ChrisHegarty
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/part-1-windows

@ChrisHegarty
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/packaging-tests-unix-sample

@elasticsearchmachine
Copy link
Collaborator

💚 Backport successful

Status Branch Result
8.4
8.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-backport Automatically create backport pull requests when merged >bug :Distributed Coordination/Network Http and internode communication implementations Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. test-windows Trigger CI checks on Windows v8.3.4 v8.4.0 v8.5.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Keep alive settings are not applied by default

6 participants