Skip to content

Detect BND computeIfAbsent CME and provide actionable diagnostic - #13000

Closed
gnodet wants to merge 1 commit into
apache:masterfrom
gnodet:fix-apache-maven-12987-concurrentmodificationexc
Closed

Detect BND computeIfAbsent CME and provide actionable diagnostic#13000
gnodet wants to merge 1 commit into
apache:masterfrom
gnodet:fix-apache-maven-12987-concurrentmodificationexc

Conversation

@gnodet

@gnodet gnodet commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #12987ConcurrentModificationException in BND/maven-bundle-plugin during dependency resolution under Maven 4.

Root Cause

BND's Jar.putResource() (bndlib ≤ 5.0.0) uses TreeMap.computeIfAbsent() with a mapping function that modifies the same TreeMap — it adds ancestor directory entries inside the mapping function:

// aQute.bnd.osgi.Jar.putResource() — bndlib 4.0.0, line 259
Map<String, Resource> s = directories.computeIfAbsent(getDirectory(path), dir -> {
    for (int n = dir.lastIndexOf('/'); n > 0; n = dir.lastIndexOf('/')) {
        dir = dir.substring(0, n);
        if (directories.containsKey(dir)) break;
        directories.put(dir, null);  // ← modifies the same TreeMap!
    }
    return new TreeMap<>();
});

This violates the computeIfAbsent() contract. JDK 17.0.13+ backported explicit CME detection for TreeMap.computeIfAbsent() (JDK-8259535), which correctly rejects this self-modification pattern. Since Maven 4 requires JDK 17+, all Maven 4 users hit this with old BND versions.

The bug was fixed in bndlib 5.1.0 (FELIX-6259, BND PR #3904).

What This PR Does

  • Catches ConcurrentModificationException specifically in DefaultBuildPluginManager.executeMojo()
  • Detects the known BND stack trace pattern (aQute.bnd.osgi.Jar.putResource)
  • Provides a clear, actionable error message:
    • Identifies the root cause (FELIX-6259 + JDK-8259535)
    • Suggests upgrading maven-bundle-plugin to 5.1.9+ or bnd-maven-plugin to 6.0.0+
  • For non-BND CMEs, provides general guidance about computeIfAbsent() issues on newer JDKs
  • Adds unit tests for the detection logic

Before (cryptic error)

[ERROR] Failed to execute goal org.apache.felix:maven-bundle-plugin:4.0.0:bundle
  on project geronimo-metrics-common:
  Execution default-bundle of goal ... failed. ConcurrentModificationException

After (actionable diagnostic)

[ERROR] Failed to execute goal org.apache.felix:maven-bundle-plugin:4.0.0:bundle
  on project geronimo-metrics-common:
  Execution default-bundle of goal ... failed: ConcurrentModificationException.
  This is a known bug in bndlib versions prior to 5.1.0 (FELIX-6259):
  BND's Jar.putResource() modifies a TreeMap inside its own computeIfAbsent() call,
  which JDK 17.0.13+ now correctly detects (JDK-8259535).
  To fix this, upgrade maven-bundle-plugin to 5.1.9+ or bnd-maven-plugin to 6.0.0+.

Affected Projects

All 7 projects identified in #12987 use old BND versions (bndlib 4.0.0–4.3.0) that predate the fix:

Project Plugin BND Version
geronimo-health maven-bundle-plugin 4.0.0 bndlib 4.0.0
geronimo-metrics maven-bundle-plugin 4.0.0 bndlib 4.0.0
geronimo-opentracing maven-bundle-plugin 4.1.0 bndlib 4.1.0
geronimo-config maven-bundle-plugin 4.2.1 bndlib ~4.3.0
geronimo-jcache-simple maven-bundle-plugin 4.2.1 bndlib ~4.3.0
aries-journaled-events bnd-maven-plugin 4.1.0 bndlib 4.1.0
aries-tx-control bnd-maven-plugin 4.1.0 bndlib 4.1.0

Test plan

  • Unit tests for BND CME detection logic (3 tests)
  • All existing maven-core tests pass (643 tests)
  • Spotless formatting check passes

🤖 Generated with Claude Code

When maven-bundle-plugin 4.x or bnd-maven-plugin 4.x throws a
ConcurrentModificationException during plugin execution, Maven now
detects the known BND bug (FELIX-6259) and provides a clear error
message with upgrade instructions instead of a cryptic CME.

Root cause: BND's Jar.putResource() uses TreeMap.computeIfAbsent()
with a mapping function that modifies the same TreeMap (adding
ancestor directories). JDK 17.0.13+ backported CME detection for
TreeMap.computeIfAbsent() (JDK-8259535), which correctly rejects
this self-modification pattern. Since Maven 4 requires JDK 17+,
all Maven 4 users hit this with old BND versions (bndlib < 5.1.0).

Fixes apache#12987

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet

gnodet commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Closing in favor of the mvnup approach — upgrading the plugin is the right fix, not adding diagnostics to maven-core.

@gnodet gnodet closed this Sep 1, 2026
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.

Maven 4: ConcurrentModificationException in BND/maven-bundle-plugin during dependency resolution

1 participant