Skip to content

Fix: Spring 7 Webflux NoSuchElementError on HttpHeaders#entrySet() - #4556

Open
mtomik wants to merge 11 commits into
elastic:mainfrom
mtomik:fix/webflux-spring-7-support
Open

Fix: Spring 7 Webflux NoSuchElementError on HttpHeaders#entrySet() #4556
mtomik wants to merge 11 commits into
elastic:mainfrom
mtomik:fix/webflux-spring-7-support

Conversation

@mtomik

@mtomik mtomik commented Aug 21, 2026

Copy link
Copy Markdown

What does this PR do?

Since the original PR is stuck for some time,
I created another one with the same commits + a bit better solution for the core of this issue.

Also when I was running these newer tests I found one more issue:

Spring7ServerFunctionalInstrumentationTest#dispatchError test was failing due to TracedSubscriber not removing the reference of the subscription on cancel() from contextMap. so the solution might be the CancellationAwareSubscription that is just the wrapper calling the discardIf() after cancel.

Is it possible that the issue was there even with older versions of reactor (from older Spring version), but now in that Spring 7 ( reactor 3.8.6 ) it was always failing.

Checklist

  • This is an enhancement of existing features, or a new feature in existing plugins
    • I have updated CHANGELOG.next-release.md
    • I have added tests that prove my fix is effective or that my feature works
    • Added an API method or config option? Document in which version this will be introduced
    • I have made corresponding changes to the documentation
  • This is a bugfix
  • This is a new plugin
    • I have updated CHANGELOG.next-release.md
    • My code follows the style guidelines of this project
    • I have made corresponding changes to the documentation
    • I have added tests that prove my fix is effective or that my feature works
    • New and existing unit tests pass locally with my changes
    • I have updated supported-technologies.md
    • Added an API method or config option? Document in which version this will be introduced
    • Added an instrumentation plugin? Describe how you made sure that old, non-supported versions are not instrumented by accident.
  • This is something else

@mtomik
mtomik requested a review from a team as a code owner August 21, 2026 12:19
@cla-checker-service

cla-checker-service Bot commented Aug 21, 2026

Copy link
Copy Markdown

💚 CLA has been signed

@github-actions

Copy link
Copy Markdown

🤖 GitHub comments

Just comment with:

  • run docs-build : Re-trigger the docs validation. (use unformatted text in the comment!)

@github-actions github-actions Bot added agent-java community Issues and PRs created by the community triage labels Aug 21, 2026
@mtomik mtomik changed the title Fix/webflux spring 7 support Fix: Spring 7 Webflux NoSuchElementError on HttpHeaders#entrySet() Aug 21, 2026
@mtomik
mtomik force-pushed the fix/webflux-spring-7-support branch from 09b0d62 to 4fb8061 Compare August 21, 2026 12:33
Comment thread CHANGELOG.next-release.md Outdated
Comment thread apm-agent-core/src/test/java/co/elastic/apm/agent/testutils/Java17OnlyTest.java Outdated
Comment thread apm-agent-core/src/test/java/co/elastic/apm/agent/testutils/Java17OnlyTest.java Outdated
Comment thread apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-testapp/pom.xml Outdated
@mtomik

mtomik commented Aug 25, 2026

Copy link
Copy Markdown
Author

thanks for the review 👍

the failed build was due to incompatibility of that sub cancel with java 7. I reworked that using Instrumentation -SubscriptionCancelInstrumentation that will call the discardIf on cancelled subscription

@mtomik
mtomik force-pushed the fix/webflux-spring-7-support branch from 4569cfe to 92bfe51 Compare August 26, 2026 11:09
jackshirazi
jackshirazi previously approved these changes Aug 26, 2026
@mergify

mergify Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

}

@Override
public ElementMatcher<? super TypeDescription> getTypeMatcher() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a common name to all the implementations we need to instrument here ? the hasSuperType is very expensive without getTypeMatcherPreFilter, so if possible adding getTypeMatcherPreFilter would be relevant here.

@mtomik mtomik Aug 26, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

only I can think of is something like this, but that probably will not narrow it much, right?

    @Override
    public ElementMatcher<? super NamedElement> getTypeMatcherPreFilter() {
        return nameContains("Subscription").or(nameContains("Subscriber"));
    }

or maybe have multiple these instrumentations by package/library that implements the CoreSubscriber ? or have just one for the implementations from reactor.core and the rest will be cleaned potentially by the GC later?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this should be fine as a first step, do you have a list of all the classes that are being currently instrumented here to verify all of them match ? If those are spring classes I would expect them to stay consistently named. If those are user-provided then it might be too narrow and we need another approach.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

the problem is, that there can come any implementation of CoreSubscriber. if we miss some thanks to this filter, the TracedSubscriber will not remove it immediately from its contextMap / subscriptionMap.

if I understand it correctly, the memory leak caused by this was always handled by GC. in this newer spring 7 came newer reactor or other library that allowed us to spot it more easily? that was at least my thought...

I had here another solution to solve it - the wrapper around that subscription (ecde26e) , but I had there compile issue with the older java versions. so maybe just try to solve that to avoid using this instrumentation?

@@ -0,0 +1,6 @@
# set to DEBUG for easier test application debugging
logging.level.root=DEBUG

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we probably don't need to have DEBUG by default here, this will make the test execution very verbose.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

it seems like it is just copy from the existing "testapp" module. so should I remove it also from there?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yes, please do that.

@jackshirazi

Copy link
Copy Markdown
Contributor

run docs-build

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

Labels

agent-java community Issues and PRs created by the community triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants