Skip to content
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

graalvm native image feature PreComputeFieldFeature disable all netty native transports #31141

Closed
czp3009 opened this issue Aug 30, 2023 · 6 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: bug A general bug
Milestone

Comments

@czp3009
Copy link

czp3009 commented Aug 30, 2023

During the graalvm native compile, the Spring provided Feature org.springframework.aot.nativex.feature.PreComputeFieldFeature will lead to all Netty native transports unavailable.

all reactor-netty related log during compile:

Field reactor.netty.internal.util.Metrics#isMicrometerAvailable set to false at build time
Field reactor.netty.internal.util.Metrics#isTracingAvailable set to false at build time
Field reactor.netty.resources.DefaultLoopIOUring#isIoUringAvailable set to false at build time
Field reactor.netty.resources.DefaultLoopEpoll#isEpollAvailable set to false at build time
Field reactor.netty.resources.DefaultLoopKQueue#isKqueueAvailable set to false at build time
Field reactor.netty.http.server.HAProxyMessageReader#isProxyProtocolAvailable set to false at build time

This is due to org.springframework.aot.nativex.feature.PreComputeFieldFeature contains such a field match pattern: https://github.com/spring-projects/spring-framework/blob/32f128b6ba118ea42f6648cda94ed1de7afa75aa/spring-core/src/main/java/org/springframework/aot/nativex/feature/PreComputeFieldFeature.java#L48C4-L48C4

Pattern.compile(Pattern.quote("reactor.") + ".*#.*Available")

This causes all the properties used by reator-netty to detect native transports to be selected.

All those properties should be init at runtime not build time to let reactor-netty correctly chose netty native transport.

This problem cause broken of using r2dbc with unix domain socket on native image.

I'm not familiar with pattern, but I think it's a good idea to skip the reactor netty properties to fix this issue.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Aug 30, 2023
@sdeleuze sdeleuze self-assigned this Aug 31, 2023
@sdeleuze sdeleuze added the theme: aot An issue related to Ahead-of-time processing label Aug 31, 2023
@sdeleuze
Copy link
Contributor

sdeleuze commented Aug 31, 2023

will lead to all Netty native transports unavailable

Could you please elaborate on what conditions more specially are false at build time but true at runtime (closed wold assumptions means that the classpath is fixed at build time and native image nature means the Operating System will be the same)?

This problem cause broken of using r2dbc with unix domain socket on native image.

Could you please share more details about the problem and a reproducer?

@sdeleuze sdeleuze added the status: waiting-for-feedback We need additional information before we can continue label Aug 31, 2023
@czp3009
Copy link
Author

czp3009 commented Aug 31, 2023

@sdeleuze When i building appliaction on a Ubuntu22.04 machine(same as runtime machine), reactor-netty native transport conditions in the logs above will always be false:

Field reactor.netty.resources.DefaultLoopIOUring#isIoUringAvailable set to false at build time
Field reactor.netty.resources.DefaultLoopEpoll#isEpollAvailable set to false at build time
Field reactor.netty.resources.DefaultLoopKQueue#isKqueueAvailable set to false at build time

Please focus on the reactor.netty.resources.DefaultLoopEpoll. in general, epoll is always available on a linux machine. But org.springframework.aot.nativex.feature.PreComputeFieldFeature disabled it.

Please see the code of DefaultLoopEpoll:

static final boolean isEpollAvailable;
  
static {
    boolean epollCheck = false;
    try {
        Class.forName("io.netty.channel.epoll.Epoll");
        epollCheck = Epoll.isAvailable();
    }
    catch (ClassNotFoundException cnfe) {
        // noop
     }
    isEpollAvailable = epollCheck;
    if (log.isDebugEnabled()) {
        log.debug("Default Epoll support : " + isEpollAvailable);
    }
}

ThrowawayClassLoader always get the value of this field as false.

After the field is always baked to false at compile time, epoll support will be disabled in runtime. Thus cause unix domain socket unavailable.

As mentioned above, this problem not only affect Epoll(on Linux), also affect other netty native transport such as KQueue(on Mac). all of these field is baked to false.

If that's still not clear enough, I can provide a sample application to reproduce it.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Aug 31, 2023
@sdeleuze
Copy link
Contributor

Could be a missing reflection entry for io.netty.channel.epoll.Epoll. Could you please try to add a src/main/resources/META-INF/native-image/reflect-config.json file on your project with the following content:

[
  {
    "name": "io.netty.channel.epoll.Epoll"
  }
]

Could you please try with that let me know if it helps? If it does, we can probably ask Reactor team to add such metadata.

@sdeleuze sdeleuze added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Aug 31, 2023
@czp3009
Copy link
Author

czp3009 commented Aug 31, 2023

@sdeleuze if i use Epoll.isAvailable() in my code, this line always return true, but the log above still says reactor.netty.resources.DefaultLoopEpoll#isEpollAvailable set to false at build time, and the still Epoll broken.

This means that it's not that Epoll can't be reflected, it's that the Field isEpollAvailable in reactor.netty.resources.DefaultLoopEpoll backed incorrectly.

i will give you a sample application later

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Aug 31, 2023
@sdeleuze
Copy link
Contributor

sdeleuze commented Aug 31, 2023

if i use Epoll.isAvailable() in my code, this line always return true

This is my expectation as well, but what I suspect is that on native without a proper reflection entry, Class.forName("io.netty.channel.epoll.Epoll") will throw a ClassNotFoundException and DefaultLoopEpoll#isEpollAvailable will be false.

That said, it could also be inlined and not require reflection metadata, so let's see with your repro.

@sdeleuze sdeleuze added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Aug 31, 2023
@czp3009
Copy link
Author

czp3009 commented Aug 31, 2023

@sdeleuze I create a demo: https://github.com/czp3009/r2dbc-native-image-domain-socket-issue-reproduce

Please follow the README to locate problem

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Aug 31, 2023
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Sep 1, 2023
This commit refines Reactor field precomputing
on native to only compute at build-time reactor-core
fields, since doing so on reactor-netty has unwanted
side effects like Epoll always disabled.

Closes spring-projectsgh-31141
@sdeleuze sdeleuze added type: bug A general bug in: core Issues in core modules (aop, beans, core, context, expression) and removed status: waiting-for-triage An issue we've not yet triaged or decided on status: feedback-provided Feedback has been provided labels Sep 1, 2023
@sdeleuze sdeleuze added this to the 6.0.12 milestone Sep 1, 2023
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Sep 1, 2023
This commit refines Reactor field precomputing
on native to only compute at build-time reactor-core
fields, since doing so on reactor-netty has unwanted
side effects like Epoll always disabled.

Closes spring-projectsgh-31141
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants