Skip to content

Support Maven POM dependency overrides in Muzzle - #12235

Closed
AlexeyKuznetsov-DD wants to merge 1 commit into
masterfrom
alexeyk/override-jetty-for-confluent
Closed

Support Maven POM dependency overrides in Muzzle#12235
AlexeyKuznetsov-DD wants to merge 1 commit into
masterfrom
alexeyk/override-jetty-for-confluent

Conversation

@AlexeyKuznetsov-DD

Copy link
Copy Markdown
Contributor

What Does This Do

Adds a mavenPomOverrides DSL to Muzzle for narrowly rewriting dependency versions in downloaded Maven POMs before Aether builds the dependency graph. The DSL can:

  • select affected artifact versions with a Maven version range
  • match dependency versions exactly, as raw POM patterns, or with Maven version ranges
  • replace matched dependency versions while leaving normal Muzzle and generated inverse directives unchanged

Uses the DSL for Kafka Connect and Confluent Schema Registry 7.x to replace ${jetty.version} and Jetty versions in [9.4.59,9.5) with the published 9.4.58.v20250814 release. This removes the Confluent skip lists so Muzzle can sample those releases normally.

Motivation

Some Confluent 7.x POMs reference unpublished Jetty versions, either through an unresolved ${jetty.version} property or as flattened literal versions. Maven model construction fails before Gradle dependency resolution rules can intervene.

PRs #12160 and #12172 worked around new occurrences by adding affected Confluent coordinates to Muzzle skip lists. This replaces that recurring skip-list maintenance with Confluent's suggested Jetty version workaround while retaining the repository setup introduced by #12180.

Additional Notes

POM overrides are opt-in and scoped to the declared artifact range. Generated inverse directives intentionally continue to use ordinary resolution.

Validation:

  • ./gradlew :buildSrc:spotlessCheck
  • ./gradlew -DrunBuildSrcTests=true :buildSrc:test --tests datadog.gradle.plugin.muzzle.MuzzleDirectiveTest --tests datadog.gradle.plugin.muzzle.MuzzlePluginFunctionalTest --tests datadog.gradle.plugin.muzzle.MuzzleMavenRepoUtilsTest — 272 passed
  • ./gradlew :dd-java-agent:instrumentation:kafka:kafka-connect-0.11:muzzle :dd-java-agent:instrumentation:confluent-schema-registry:confluent-schema-registry-4.1:muzzle — 66 passed
  • repository-wide formatting checks run by the commit hook

Contributor Checklist

Jira ticket: N/A

@AlexeyKuznetsov-DD AlexeyKuznetsov-DD added type: bug fix Bug fix comp: tooling Build & Tooling inst: kafka Kafka instrumentation tag: ai generated Largely based on code generated by an AI or LLM tag: no release notes Changes to exclude from release notes labels Aug 19, 2026 — with ChatGPT Codex Connector
@AlexeyKuznetsov-DD AlexeyKuznetsov-DD self-assigned this Aug 19, 2026
@AlexeyKuznetsov-DD
AlexeyKuznetsov-DD marked this pull request as ready for review August 19, 2026 01:37
@AlexeyKuznetsov-DD
AlexeyKuznetsov-DD requested review from a team as code owners August 19, 2026 01:37
@AlexeyKuznetsov-DD
AlexeyKuznetsov-DD requested review from ValentinZakharov and manuel-alvarez-alvarez and removed request for a team August 19, 2026 01:37
@datadog-datadog-us1-prod

datadog-datadog-us1-prod Bot commented Aug 19, 2026

Copy link
Copy Markdown

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 58.39% (-0.05%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 3fc05d4 | Docs | View more details | Give us feedback!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3fc05d491d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +165 to +169
val session = DefaultRepositorySystemSession(baseSession).apply {
repositoryListener = ChainedRepositoryListener.newInstance(
repositoryListener,
MavenDependencyVersionOverrideListener(muzzleDirective)
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Isolate the local Maven repository per override directive

When one instrumentation project declares multiple mavenPomOverrides directives that resolve a shared POM, this session clone retains the base session's LocalRepositoryManager, while the listener writes each patched POM back into that shared temporary repository. A later directive therefore reads the earlier directive's modified XML; for example, after one directive replaces 1.0 with 2.0, another directive matching 1.0 to produce 3.0 no longer matches and silently gets 2.0. This makes resolution order-dependent despite the DSL documenting overrides as directive-scoped, so each override resolution should use an isolated local repository or patch a disposable copy.

Useful? React with 👍 / 👎.

Comment on lines +300 to +301
val versionMatch = VERSION_ELEMENT.find(element, groupMatch.range.last + 1)
?: return@replace element

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Skip commented tags when locating dependency versions

When a dependency contains a commented-out version before its active version, such as <!-- <version>old</version> -->, this unanchored search selects and rewrites the tag inside the comment. The active bad version remains unchanged, so Maven model construction still fails even though the configured group and version selector match the dependency. The version lookup should ignore XML comments or operate on parsed XML rather than selecting the first textual <version> after groupId.

Useful? React with 👍 / 👎.

@datadog-datadog-us1-prod datadog-datadog-us1-prod Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Datadog Autotest: FAIL

Cloning the Aether session retains its shared local repository, allowing one directive’s in-place POM rewrite to alter a later directive targeting the same artifact. The later directive can consequently resolve and validate the wrong dependency graph.

Open Bits AI session

🤖 Datadog Autotest · Commit 3fc05d4 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

baseSession: RepositorySystemSession,
defaultRepos: List<RemoteRepository> = defaultMuzzleRepos()
): Set<File> {
val session = DefaultRepositorySystemSession(baseSession).apply {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Isolate rewritten POMs between directives

Muzzle can validate the wrong classpath and produce false compatibility passes or failures when named directives use different overrides for the same artifact version.

Assertion details
  • Input: Two named Muzzle directives resolve the same artifact version in one project but specify different POM dependency-version overrides.
  • Expected: Each directive should apply its override configuration independently to the artifact's original published POM and resolve its own dependency graph.
  • Actual: DefaultRepositorySystemSession(baseSession) retains the base session's localRepositoryManager. The override listener then rewrites the cached POM in place, so a later directive reads the first directive's modified POM; its own exact match can miss and it can resolve the first directive's dependency graph. The resolution needs a pristine per-override POM cache or restoration of original POM contents, with a multi-directive regression test.

Was this helpful? React 👍 or 👎
🤖 Datadog Autotest · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

@pr-commenter

pr-commenter Bot commented Aug 19, 2026

Copy link
Copy Markdown

Kafka / consumer-benchmark

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alexeyk/override-jetty-for-confluent
git_commit_date 1787065419 1787102730
git_commit_sha bc42364 3fc05d4
See matching parameters
Baseline Candidate
ci_job_date 1787103862 1787103862
ci_job_id 1963569485 1963569485
ci_pipeline_id 131767493 131767493
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
jdkVersion 11.0.25 11.0.25
jmhVersion 1.36 1.36
jvm /usr/lib/jvm/java-11-openjdk-amd64/bin/java /usr/lib/jvm/java-11-openjdk-amd64/bin/java
jvmArgs -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/go/src/github.com/DataDog/apm-reliability/dd-trace-java/platform/src/consumer-benchmark/build/tmp/jmh -Duser.country=US -Duser.language=en -Duser.variant -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/go/src/github.com/DataDog/apm-reliability/dd-trace-java/platform/src/consumer-benchmark/build/tmp/jmh -Duser.country=US -Duser.language=en -Duser.variant
vmName OpenJDK 64-Bit Server VM OpenJDK 64-Bit Server VM
vmVersion 11.0.25+9-post-Ubuntu-1ubuntu122.04 11.0.25+9-post-Ubuntu-1ubuntu122.04

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 3 metrics, 0 unstable metrics.

See unchanged results
scenario Δ mean throughput
scenario:not-instrumented/KafkaConsumerBenchmark.benchConsume same
scenario:only-tracing-dsm-disabled-benchmarks/KafkaConsumerBenchmark.benchConsume same
scenario:only-tracing-dsm-enabled-benchmarks/KafkaConsumerBenchmark.benchConsume same

@dd-octo-sts

dd-octo-sts Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 14.05 s 13.97 s [-0.1%; +1.3%] (no difference)
startup:insecure-bank:tracing:Agent 12.94 s 13.00 s [-1.4%; +0.5%] (no difference)
startup:petclinic:appsec:Agent 16.95 s 16.71 s [+0.5%; +2.5%] (maybe worse)
startup:petclinic:iast:Agent 16.90 s 16.99 s [-1.1%; +0.1%] (no difference)
startup:petclinic:profiling:Agent 16.66 s 16.85 s [-2.1%; -0.1%] (maybe better)
startup:petclinic:sca:Agent 16.73 s 16.56 s [-0.1%; +2.2%] (no difference)
startup:petclinic:tracing:Agent 15.66 s 16.08 s [-6.8%; +1.6%] (no difference)

Commit: 3fc05d49 · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

@AlexeyKuznetsov-DD
AlexeyKuznetsov-DD marked this pull request as draft August 19, 2026 16:55
@AlexeyKuznetsov-DD

Copy link
Copy Markdown
Contributor Author

Fix is too complicated.

@AlexeyKuznetsov-DD
AlexeyKuznetsov-DD deleted the alexeyk/override-jetty-for-confluent branch August 19, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: tooling Build & Tooling inst: kafka Kafka instrumentation tag: ai generated Largely based on code generated by an AI or LLM tag: no release notes Changes to exclude from release notes type: bug fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant