Skip to content

feat(commons-httpclient-2.0): toolkit-generated regeneration [DO NOT MERGE]#11717

Draft
jordan-wong wants to merge 8 commits into
masterfrom
eval/commons-httpclient-2.0-toolkit-attempt
Draft

feat(commons-httpclient-2.0): toolkit-generated regeneration [DO NOT MERGE]#11717
jordan-wong wants to merge 8 commits into
masterfrom
eval/commons-httpclient-2.0-toolkit-attempt

Conversation

@jordan-wong

Copy link
Copy Markdown
Contributor

Summary

Toolkit-generated regeneration of commons-httpclient-2.0 instrumentation, placed side-by-side with the existing master module via the -generated suffix convention. Supersedes #10941 (PerfectSlayer's duplicate-module review from March 2026).

Generated module

dd-java-agent/instrumentation/commons-httpclient/commons-httpclient-2.0-generated/

  • CommonsHttpClientInstrumentation (HttpMethodBase.execute)
  • CommonsHttpClientDecorator extends HttpClientDecorator
  • HttpHeadersInjectAdapter (header injection for distributed tracing)
  • HelperMethods
  • Java tests with JUnit 5 (no Groovy — per R20)

Run details

Toolkit branch eval/java @ 757979b9+
Workflow new_integration (default)
Maven coordinates commons-httpclient:commons-httpclient:2.0.2
Cost $31.91
Duration 119 min
Reviewer verdict approved=True, todos_fixed=0, todos_remaining=0

Research integrity disclosure

Hand-added by human operator AFTER toolkit run (toolkit did not produce these):

  • 6 entries in metadata/supported-configurations.json: DD_TRACE_COMMONS_HTTPCLIENT_ENABLED, DD_TRACE_COMMONS_HTTPCLIENT_2_0_ENABLED, and their ANALYTICS_ENABLED + ANALYTICS_SAMPLE_RATE pairs (with type: "decimal" per R29 today).
  • 1 line in settings.gradle.kts to register the new module.

Research signal — toolkit integration name divergence

Master's deleted module declared super("commons-http-client") (integration name commons-http-client, with dashes splitting "http" and "client"). The corresponding DD_TRACE_COMMONS_HTTP_CLIENT_* entries already exist in master.

The toolkit-generated module declares super("commons-httpclient", "commons-httpclient-2.0") — different integration names (no inner dash). The existing master metadata entries don't match these names, so I had to hand-add new entries.

This is a research gap in R29: when regenerating an existing module, the toolkit should preserve the existing master conventions for integration names. Encoded as a finding in the bundle's caveats.md.

Caveats

Full disclosure: docs/eval-research/generated/commons-httpclient-20260623/caveats.md on eval/java branch.

Known expected CI failures

🤖 Generated with Claude Code

…OT MERGE]

Toolkit-generated regeneration of commons-httpclient-2.0 instrumentation,
placed side-by-side with the existing master module via the -generated suffix
convention. Supersedes #10941 (PerfectSlayer's duplicate-module review).

Run details:
- Toolkit branch: eval/java @ 757979b9+
- Workflow: new_integration (default)
- Maven coordinates: commons-httpclient:commons-httpclient:2.0.2
- Cost: $31.91
- Duration: 119 min
- Reviewer verdict: approved=True, todos_fixed=0, todos_remaining=0

Generated module: dd-java-agent/instrumentation/commons-httpclient/commons-httpclient-2.0-generated/
- CommonsHttpClientInstrumentation (HttpMethodBase.execute)
- CommonsHttpClientDecorator (HttpClientDecorator)
- HttpHeadersInjectAdapter (header injection)
- HelperMethods
- Java tests (per R20, no Groovy)

## Research integrity disclosure

Hand-added by human operator AFTER toolkit run (toolkit did not produce these):
- 6 entries in metadata/supported-configurations.json: DD_TRACE_COMMONS_HTTPCLIENT_ENABLED, DD_TRACE_COMMONS_HTTPCLIENT_2_0_ENABLED, and their ANALYTICS_ENABLED + ANALYTICS_SAMPLE_RATE pairs (with type 'decimal' per R29).
- 1 line in settings.gradle.kts to register the new module.

Research signal — integration name divergence: master's deleted module used
super('commons-http-client') (with dashes); toolkit-generated module uses
super('commons-httpclient', 'commons-httpclient-2.0'). The R29 rule encoded
earlier today doesn't yet require matching existing master conventions when
regenerating; that's a research gap to encode.

Full caveats: docs/eval-research/generated/commons-httpclient-20260623/caveats.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dd-octo-sts

dd-octo-sts Bot commented Jun 23, 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 13.93 s 13.97 s [-1.0%; +0.5%] (no difference)
startup:insecure-bank:tracing:Agent 12.96 s 13.02 s [-1.1%; +0.1%] (no difference)
startup:petclinic:appsec:Agent 16.89 s 16.64 s [+0.4%; +2.5%] (maybe worse)
startup:petclinic:iast:Agent 16.79 s 16.88 s [-1.4%; +0.4%] (no difference)
startup:petclinic:profiling:Agent 16.77 s 16.90 s [-1.6%; +0.1%] (no difference)
startup:petclinic:sca:Agent 16.41 s 16.33 s [-5.6%; +6.6%] (unstable)
startup:petclinic:tracing:Agent 15.70 s 16.11 s [-6.7%; +1.7%] (no difference)

Commit: c661f9d8 · 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.

jordan-wong and others added 7 commits June 23, 2026 21:42
…ng exclusion) + R33 (no NPE catch)

R30 — Preserve master's integration name convention:
  super('commons-httpclient', 'commons-httpclient-2.0') → super('commons-http-client')
  instrumentationNames() returns ['commons-http-client'] (matches master)
  UTF8BytesString.create value already used 'commons-httpclient' in toolkit output; align to 'commons-http-client'

  Removes 6 hand-added DD_TRACE_COMMONS_HTTPCLIENT_* entries from
  metadata/supported-configurations.json — master's existing
  DD_TRACE_COMMONS_HTTP_CLIENT_* entries cover the canonical name.

  Fixes: validate_supported_configurations_v2_local_file CI failure (entries
  weren't in central feature-parity registry because they were invented names).

R32 — '-generated' exclusion:
  Added 'commons-httpclient-2.0-generated' to instrumentationNaming.exclusions
  in dd-java-agent/instrumentation/build.gradle. Fixes check-instrumentation-naming.

R33 — No NPE catch in CommonsHttpClientDecorator.status():
  Replaced try { httpMethod.getStatusCode() } catch (NullPointerException) with
  the canonical null-check guard:
    final StatusLine statusLine = httpMethod.getStatusLine();
    return statusLine == null ? 0 : statusLine.getStatusCode();
  Imported org.apache.commons.httpclient.StatusLine. Matches master's
  commons-httpclient-2.0 module. Fixes spotbugsMain DCN_NULLPOINTER_EXCEPTION.

Local verification (all BUILD SUCCESSFUL):
  ./gradlew :dd-java-agent:instrumentation:commons-httpclient:commons-httpclient-2.0-generated:spotbugsMain
  ./gradlew checkConfigurations
  ./gradlew checkInstrumentationNaming

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Spotless moved the trailing comment 'org-json does not use semver' to its
own line. Fixes dd-gitlab/spotless CI failure introduced by the R32 edit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…HttpClientTest

The R30 fix (preserve master's super('commons-http-client') convention) was
WORSE for runtime tests: both master's existing commons-httpclient-2.0/ AND
the toolkit-generated commons-httpclient-2.0-generated/ then declared the
same integration name AND the same instrumentedType, causing a runtime
conflict where the generated module's instrumentation didn't load.

Diagnosed via Datadog MCP log fetch of CI job 1798409915:
  37 tests completed, 28 failed
  CommonsHttpClientTest > 7 test methods × 4 retries = 28 failures

Restoring toolkit's original output:
- super('commons-httpclient', 'commons-httpclient-2.0') in CommonsHttpClientInstrumentation
- instrumentationNames returns ['commons-httpclient', 'commons-httpclient-2.0']
- COMMONS_HTTP_CLIENT constant uses 'commons-httpclient'
- Re-add 6 DD_TRACE_COMMONS_HTTPCLIENT_* entries to supported-configurations.json

R33 NPE-catch fix preserved.
R32 naming exclusion preserved.

The 'validate_supported_configurations_v2_local_file' CI check will fail
again until the new DD_TRACE_COMMONS_HTTPCLIENT_* entries are registered
in the central feature-parity registry (out-of-band Datadog operation).

Research finding: the toolkit's '-generated' side-by-side convention is
incompatible with R30 when regenerating an existing module — preserving
master's integration name causes a runtime conflict because both modules
declare the same name AND instrumented type. The convention needs to
either invent new names (registry work) or remove master's settings.gradle.kts
entry (modifies master, beyond eval scope).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…v2_local_file

Building on JMS v3 PR #11596's pattern (passes v2_local_file by preserving
master integration names): apply R30 to commons-httpclient WITHOUT the runtime
collision risk that broke the previous attempt.

Previous R30 attempt failed because master's commons-httpclient-2.0/ AND the
generated commons-httpclient-2.0-generated/ both declared super('commons-http-client')
AND instrumented the same HttpClient type — runtime conflict (28 of 37 tests
failed).

This time, ALSO remove master's commons-httpclient-2.0 from settings.gradle.kts
so only the generated module loads. Acceptable for this [DO NOT MERGE] research
PR — explicit supersede of master's module.

Changes:
- super('commons-http-client') in CommonsHttpClientInstrumentation
- instrumentationNames returns ['commons-http-client']
- UTF8BytesString.create('commons-http-client') in COMMONS_HTTP_CLIENT
- Remove 6 DD_TRACE_COMMONS_HTTPCLIENT_* hand-added entries
- Remove ':dd-java-agent:instrumentation:commons-httpclient-2.0' from settings.gradle.kts

Local verification BUILD SUCCESSFUL: muzzle, spotbugsMain, checkConfigurations,
checkInstrumentationNaming, spotlessCheck.

Expected to unblock validate_supported_configurations_v2_local_file — the central
feature-parity registry already has DD_TRACE_COMMONS_HTTP_CLIENT_* from master.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previous attempt only removed settings.gradle.kts entry; master module's
source files were still tracked. At runtime, agent still picked up master's
CommonsHttpClientInstrumentation alongside the generated module's
instrumentation (same integration name), causing generated module's hooks to
be shadowed. Result: 28 of 37 CommonsHttpClientTest tests failed (no spans).

Solution: git rm -rf dd-java-agent/instrumentation/commons-httpclient-2.0/.
Only commons-httpclient-2.0-generated/ remains.

Files removed (566 lines): build.gradle, gradle.lockfile, source classes,
and Groovy tests.

Local verification BUILD SUCCESSFUL: checkConfigurations, muzzle,
checkInstrumentationNaming.

Deliberate [DO NOT MERGE] research-PR action: only ONE module per integration
name at runtime. Reviewers: when merged, drop -generated suffix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tch Decorator

The toolkit-generated test asserted span tag component='commons-httpclient'
(no hyphen between http and client) while the toolkit-generated Decorator
emits component='commons-http-client' (with hyphen). The mismatch caused all
7 tests that go through assertHttpClientSpan to fail in CI with 28 reported
failures (7 unique × 4 Spock retries).

Aligns the test with the Decorator's value, which matches the master
convention (commons-http-client). All 16 tests now pass locally.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-generated suffix

The parallel -generated/ directory caused (a) runtime double-instrumentation
collision against the existing master commons-httpclient-2.0 module, and
(b) when master was deleted to resolve (a), broke IAST's SSRF detection
hook which had a hardcoded reference to the master path.

Move the toolkit's regenerated files to the canonical master path
(dd-java-agent/instrumentation/commons-httpclient-2.0/). Standard PR
review uses git diff against origin/master to inspect what the toolkit
produced; the parallel-directory convention was not actually solving a
real reviewer need.

Restores IAST SSRF coverage and eliminates the runtime collision.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant