Skip to content

Add workaround for JDK-8287073 to tests#2052

Merged
Godin merged 4 commits into
jacoco:masterfrom
Godin:JDK-8287073
Mar 3, 2026
Merged

Add workaround for JDK-8287073 to tests#2052
Godin merged 4 commits into
jacoco:masterfrom
Godin:JDK-8287073

Conversation

@Godin
Copy link
Copy Markdown
Member

@Godin Godin commented Feb 17, 2026

No description provided.

@Godin Godin added this to the 0.8.15 milestone Feb 17, 2026
@Godin Godin self-assigned this Feb 17, 2026
@Godin Godin changed the title Add workaround for JDK-8287073 Add workaround for JDK-8287073 in tests Feb 17, 2026
@Godin Godin marked this pull request as ready for review February 17, 2026 23:20
@Godin Godin requested a review from marchof February 17, 2026 23:20
@marchof
Copy link
Copy Markdown
Member

marchof commented Feb 18, 2026

I have two questions that may be clarified in the comment:

  1. Where did we see this problem?
  2. Why does calling ManagementFactory.getPlatformMBeanServer() twice fix the problem?

Also, why don't we need the same workaround here in our production code?

@Godin
Copy link
Copy Markdown
Member Author

Godin commented Feb 18, 2026

@marchof

Where did we see this problem?

There are two commits in this PR and first one that merely adds comment shows that test fails on JDK 18 in both Azure Pipelines and GitHub Actions - quoting its build log https://github.com/jacoco/jacoco/actions/runs/22118309518/job/63932012624

Running org.jacoco.agent.rt.internal.AgentTest
Tests run: 19, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.059 sec <<< FAILURE! - in org.jacoco.agent.rt.internal.AgentTest
startup_should_not_register_mbean_when_disabled(org.jacoco.agent.rt.internal.AgentTest)  Time elapsed: 0.037 sec  <<< ERROR!
java.lang.NullPointerException: Cannot invoke "jdk.internal.platform.CgroupInfo.getMountPoint()" because "anyController" is null
	at org.jacoco.agent.rt.internal.AgentTest.startup_should_not_register_mbean_when_disabled(AgentTest.java:167)

First time I noticed this failure in my fork yesterday, multiple re-runs demonstrate that this test steadily fails only on JDK 18. So I'm ready to bet that restart of build on master without any changes will fail the same way.

I do not know why this started to happen just recently and why only on JDK 18 - to me seems that much more versions should be affected according to https://bugs.openjdk.org/browse/JDK-8287073 which states that fix was made in 19 and backported only to LTS versions 17, 11, and 8.

Why does calling ManagementFactory.getPlatformMBeanServer() twice fix the problem?

This is quick attempt to do workaround based on shallow observation that several tests use ManagementFactory.getPlatformMBeanServer() while only startup_should_not_register_mbean_when_disabled fails, honestly no other investigations - even did not checked order of tests.

Here is my wield guess: during first call initialization of some field in some component causes NPE, so field ends up with default null value, which second call ignores as missing optional component or components are still in some improper state and might misbehave, but at least paths and outcomes exercised by our tests seem to work.

Why don't we need the same workaround here in our production code?

Most important argument for/from me to apply this only in tests is that otherwise user code that calls java.lang.management.ManagementFactory.getPlatformMBeanServer() without clear/obvious reasons might behave differently when executed with and without JaCoCo Agent.

Such change of behavior of user code sounds similar to #1334 which clearly an example of bad thing. Making an analogy with physic - to me JaCoCo Agent is observer and we should do our best to minimize observer effect. Due to observer effect, people already undeservedly blame JaCoCo when JVM crashes with SIGSEGV caused by bug in HotSpot - see for example #1801.

And while someone might argue that in this case it will be example of good thing, IMO it is not responsibility of JaCoCo Agent to deliver workarounds for bugs in JDK 😉

@Godin
Copy link
Copy Markdown
Member Author

Godin commented Feb 19, 2026

@marchof Also can be observed right now in #2023 preventing its merge.

Alternative options are: "hammer" one - stop building with JDK 18 completely, or quarantine/disable failing test.

@Godin
Copy link
Copy Markdown
Member Author

Godin commented Feb 19, 2026

still in some improper state and might misbehave, but at least paths and outcomes exercised by our tests seem to work

Seems to be the case - even if second invocation of ManagementFactory.getPlatformMBeanServer() succeeds as well as other operations in our tests, invocations of ManagementFactory.getOperatingSystemMXBean() will be throwing same NPE.

Copy link
Copy Markdown
Member

@marchof marchof left a comment

Choose a reason for hiding this comment

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

Many thanks for the detailed explanation!

@reta
Copy link
Copy Markdown

reta commented Feb 19, 2026

@Godin @marchof sorry folks to chime in, we've also observed this issue while running builds on older JDKs (no changes to codebases whatsoever), what is interesting is that if switching GA runners from Ubuntu 24.04 to 22.04 seems to fix the problem (however that could be temporary as well), just some data points

@Godin
Copy link
Copy Markdown
Member Author

Godin commented Feb 19, 2026

@reta thanks for the info! ❤️
We moved from deprecated ubuntu-20.04 to ubuntu-24.04 in #1876.
While downgrade to ubuntu-22.04 might be possible, and while most likely it will enter deprecation cycle no earlier than in 2027, I prefer to keep latest stable.

@marchof
Copy link
Copy Markdown
Member

marchof commented Feb 19, 2026

@reta wait, did you see a stack trace specific to JaCoCo? Or did this happen in your code only?

@reta
Copy link
Copy Markdown

reta commented Feb 19, 2026

@reta wait, did you see a stack trace specific to JaCoCo? Or did this happen in your code only?

@marchof Sorry, should have been more clear, not jacoco related (yet), this is specific to our project (https://github.com/Opensearch-project/opensearch-java), but just all the same cause (the checks started to fails out of the blue for some older JDKs)

@Godin
Copy link
Copy Markdown
Member Author

Godin commented Feb 19, 2026

@marchof agent registers its MBean at startup which is guarded by agent option jmx whose default value is false

So it can fail only if explicitly enabled:

java -javaagent:jacoco-0.8.14/lib/jacocoagent.jar=jmx=true -version

and

java.lang.NullPointerException: Cannot invoke "jdk.internal.platform.CgroupInfo.getMountPoint()" because "anyController" is null
	at java.base/jdk.internal.platform.cgroupv2.CgroupV2Subsystem.getInstance(CgroupV2Subsystem.java:80)
	at java.base/jdk.internal.platform.CgroupSubsystemFactory.create(CgroupSubsystemFactory.java:114)
	at java.base/jdk.internal.platform.CgroupMetrics.getInstance(CgroupMetrics.java:177)
	at java.base/jdk.internal.platform.SystemMetrics.instance(SystemMetrics.java:29)
	at java.base/jdk.internal.platform.Metrics.systemMetrics(Metrics.java:58)
	at java.base/jdk.internal.platform.Container.metrics(Container.java:43)
	at jdk.management/com.sun.management.internal.OperatingSystemImpl.<init>(OperatingSystemImpl.java:182)
	at jdk.management/com.sun.management.internal.PlatformMBeanProviderImpl.getOperatingSystemMXBean(PlatformMBeanProviderImpl.java:280)
	at jdk.management/com.sun.management.internal.PlatformMBeanProviderImpl$3.nameToMBeanMap(PlatformMBeanProviderImpl.java:199)
	at java.management/java.lang.management.ManagementFactory.lambda$getPlatformMBeanServer$0(ManagementFactory.java:489)
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1779)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at java.management/java.lang.management.ManagementFactory.getPlatformMBeanServer(ManagementFactory.java:490)
	at org.jacoco.agent.rt.internal_29a6edd.JmxRegistration.<init>(JmxRegistration.java:36)
	at org.jacoco.agent.rt.internal_29a6edd.Agent.startup(Agent.java:131)
	at org.jacoco.agent.rt.internal_29a6edd.Agent.getInstance(Agent.java:54)
	at org.jacoco.agent.rt.internal_29a6edd.PreMain.premain(PreMain.java:47)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:577)
	at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:491)
	at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:503)

in such case
clearly points to https://bugs.openjdk.org/browse/JDK-8287073
and is expected outcome per #2052 (comment)


Also I just re-triggered build of #2023 and for some reason failure is gone 😅

@Godin Godin marked this pull request as draft February 19, 2026 21:35
@Godin Godin changed the title Add workaround for JDK-8287073 in tests Add workaround for JDK-8287073 to tests Mar 3, 2026
@Godin
Copy link
Copy Markdown
Member Author

Godin commented Mar 3, 2026

Failures started to happen again, so I'm merging this workaround.

@Godin Godin marked this pull request as ready for review March 3, 2026 16:20
@Godin Godin enabled auto-merge (squash) March 3, 2026 16:20
@Godin Godin merged commit 85ca577 into jacoco:master Mar 3, 2026
80 of 82 checks passed
@Godin Godin deleted the JDK-8287073 branch March 3, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants