Skip to content

Commit 084453f

Browse files
committed
Improved classLoaderMatcher comments
1 parent f58fa79 commit 084453f

22 files changed

Lines changed: 91 additions & 77 deletions

File tree

.github/agents/knowledge/javaagent-module-patterns.md

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,45 @@ class suffices for a simple version boundary — use multiple classes only when:
8282
present (e.g., Jersey checks both the JAX-RS spec API and the Jersey implementation class;
8383
AWS SDK Lambda checks both the Lambda module and JSON protocol core).
8484

85-
Place a comment **above each class name string** stating its version role and matcher shape:
85+
For multi-class checks or negated exclusions, place a comment **above each class name string**
86+
stating its version role and matcher shape:
8687

8788
- **Positive floor class** in `hasClassesNamed(...)` (proves "at least version X"):
88-
use `// added in X.Y`.
89+
use `// added in X.Y`, optionally followed by brief parenthetical context only when it adds
90+
interesting, non-duplicative signal.
8991
- **Positive ceiling class** in `hasClassesNamed(...)` (proves "not yet version Y"):
90-
use `// removed in Y.Z`.
92+
use `// removed in Y.Z`, optionally followed by brief parenthetical context only when it
93+
adds interesting, non-duplicative signal.
9194
- **Negated exclusion class** in `not(hasClassesNamed(...))` or
92-
`.and(not(hasClassesNamed(...)))`: use `// added in Y.Z`, because the class's presence
93-
starts excluding `Y.Z+`.
95+
`.and(not(hasClassesNamed(...)))`: use `// added in Y.Z`, optionally followed by brief
96+
parenthetical context only when it adds interesting, non-duplicative signal, because the
97+
class's presence starts excluding `Y.Z+`.
98+
99+
Short parenthetical details are allowed only when they add interesting, non-duplicative
100+
signal beyond the version role itself, for example native instrumentation notes, backport
101+
context, or namespace rename notes.
94102

95103
A single **positive** landmark class can sometimes provide **both** bounds: its presence
96104
proves the module is at least version `X.Y`, and the same class disappears in `Y.Z`, so
97105
its presence also excludes `Y.Z+`. In that case, a combined comment such as
98106
`// added in X.Y, removed in Y.Z` is appropriate.
99107

108+
For a single-item `hasClassesNamed(...)` check, prefer the compact form with the version
109+
comment above the statement or expression that uses it, instead of splitting the sole string
110+
onto its own line. For example:
111+
112+
```java
113+
// added in 3.0
114+
return hasClassesNamed("jakarta.faces.context.FacesContext");
115+
```
116+
117+
And for a single negated exclusion:
118+
119+
```java
120+
// added in 8.10 (native OTel support)
121+
.and(not(hasClassesNamed("co.elastic.clients.transport.instrumentation.Instrumentation")));
122+
```
123+
100124
**How to identify ceiling classes**: check whether a **newer sibling module** exists for
101125
the same library (e.g., `mongo-4.0` next to `mongo-3.7`). If the newer module's
102126
`classLoaderMatcher()` checks a different variant of the same class (e.g.,
@@ -140,7 +164,7 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
140164
return hasClassesNamed(
141165
// added in 3.7
142166
"com.mongodb.MongoClientSettings$Builder",
143-
// removed in 4.0 — excludes driver 4.0+ where the 4.0 module takes over
167+
// removed in 4.0 — replaced by com.mongodb.internal.async.SingleResultCallback
144168
"com.mongodb.async.SingleResultCallback");
145169
}
146170
```
@@ -187,14 +211,19 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
187211
is correct when muzzle can detect version boundaries on its own (the common case). Only
188212
flag a *missing* override when the module targets a specific version range and the
189213
versioning signal (added/removed landmark class) is not part of the classes muzzle inspects.
190-
- **Version comments on landmark classes.** For multi-class checks, `.and(not(...))`
191-
chains, or cases where the landmark version differs from the module's base version,
192-
each `hasClassesNamed()` call must have a `//` comment stating the class's **role**:
193-
- Positive floor class → `// added in X.Y` (class introduced in version X.Y).
194-
- Positive ceiling class → `// removed in Y.Z` (class removed in version Y.Z, ensuring
195-
the module does not activate on Y.Z+).
196-
- Negated exclusion class in `not(hasClassesNamed(...))``// added in Y.Z` (class
197-
introduced in version Y.Z, so its presence excludes Y.Z+).
214+
- **Version comments on landmark classes.** For multi-class checks or cases where the
215+
landmark version differs from the module's base version, each `hasClassesNamed()` call
216+
must have a `//` comment stating the class's **role**. For a single-item
217+
`hasClassesNamed(...)` check, including a negated exclusion in `.and(not(...))`, prefer
218+
the compact form with the comment above the statement or expression instead of splitting
219+
the sole string onto its own line:
220+
- Positive floor class → `// added in X.Y` (optionally with brief, non-duplicative
221+
parenthetical context such as `renamed from javax` or `backported to 2.12.3`).
222+
- Positive ceiling class → `// removed in Y.Z` (optionally with brief, non-duplicative
223+
parenthetical context such as `replaced by jakarta variant` or `moved to internal.async`).
224+
- Negated exclusion class in `not(hasClassesNamed(...))``// added in Y.Z`
225+
(optionally with brief, non-duplicative parenthetical context such as `native OTel
226+
support` or `shaded into core module`).
198227
- Single positive class that serves as both floor and ceiling → include both boundaries,
199228
e.g. `// added in X.Y, removed in Y.Z`.
200229
Do not use `// added in` for a **positive** ceiling class — that states when the class
@@ -204,13 +233,15 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
204233
To identify ceiling classes, check if a newer sibling module's `classLoaderMatcher()`
205234
checks a different variant or replacement class.
206235
- **Single-class landmark comments are required.** When a single-class
207-
`hasClassesNamed(...)` check establishes the module's lower bound, add an inline
208-
`// added in X.Y` comment. If that same class also establishes the upper bound because
209-
it is removed or replaced in a newer sibling version, include that fact too, e.g.
210-
`// added in X.Y, removed in Y.Z`. First validate each stated boundary from repository
211-
or upstream evidence; do not infer versions from the module name alone. Flag a missing
212-
boundary comment in this case, and do not flag an existing dual-role comment for removal
213-
unless it is demonstrably wrong.
236+
`hasClassesNamed(...)` check establishes the module's lower bound, or when a single-class
237+
negated check establishes an excluded upper range, prefer the compact form with the
238+
version comment immediately above the statement or expression that uses the matcher.
239+
Parenthetical context is fine only when it adds interesting, non-duplicative signal. If
240+
the same positive class also establishes the upper bound because it is removed or replaced
241+
in a newer sibling version, include that fact too, e.g. `// added in X.Y, removed in Y.Z`.
242+
First validate each stated boundary from repository or upstream evidence; do not infer
243+
versions from the module name alone. Flag a missing boundary comment in this case, and do
244+
not flag an existing dual-role comment for removal unless it is demonstrably wrong.
214245
- Prefer **one landmark class** per version boundary — choose the most stable/specific class.
215246
- Pair with **muzzle config** (`assertInverse.set(true)`) for full coverage.
216247
- Use `hasClassesNamed(...)` (from `AgentElementMatchers`) — not raw ByteBuddy matchers.

instrumentation/azure-core/azure-core-1.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/azurecore/v1_14/AzureSdkInstrumentationModule.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,12 @@ public void injectClasses(ClassInjector injector) {
5353

5454
@Override
5555
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
56-
return hasClassesNamed(
57-
// added in 1.14.0
58-
"com.azure.core.util.tracing.Tracer")
59-
// this is needed to prevent this instrumentation from being applied to azure-core 1.19+
60-
.and(
61-
not(
62-
hasClassesNamed(
63-
// added in 1.19.0
64-
"com.azure.core.util.tracing.StartSpanOptions")))
65-
.and(
66-
not(
67-
hasClassesNamed(
68-
// added in 1.19.0
69-
"com.azure.core.tracing.opentelemetry.OpenTelemetryTracer")));
56+
// added in azure-core 1.14.0
57+
return hasClassesNamed("com.azure.core.util.tracing.Tracer")
58+
// added in azure-core 1.19.0
59+
.and(not(hasClassesNamed("com.azure.core.util.tracing.StartSpanOptions")))
60+
// added in azure-core-tracing-opentelemetry 1.0.0-beta.47 (native OTel support)
61+
.and(not(hasClassesNamed("com.azure.core.tracing.opentelemetry.OpenTelemetryTracer")));
7062
}
7163

7264
@Override

instrumentation/azure-core/azure-core-1.19/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/azurecore/v1_19/AzureSdkInstrumentationModule.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ public void injectClasses(ClassInjector injector) {
5353

5454
@Override
5555
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
56-
// this class was introduced in azure-core 1.19
56+
// added in azure-core 1.19
5757
return hasClassesNamed("com.azure.core.util.tracing.StartSpanOptions")
58-
// OpenTelemetryTracer was introduced in azure-core-tracing-opentelemetry 1.0.0-beta.47
58+
// added in azure-core-tracing-opentelemetry 1.0.0-beta.47 (native OTel support)
5959
.and(not(hasClassesNamed("com.azure.core.tracing.opentelemetry.OpenTelemetryTracer")))
60-
// TracerProvider was introduced in azure-core 1.36
60+
// added in azure-core 1.36
6161
.and(not(hasClassesNamed("com.azure.core.util.tracing.TracerProvider")));
6262
}
6363

instrumentation/azure-core/azure-core-1.36/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/azurecore/v1_36/AzureSdkInstrumentationModule.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ public void injectClasses(ClassInjector injector) {
5555

5656
@Override
5757
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
58-
// TracerProvider was introduced in azure-core 1.36
58+
// added in azure-core 1.36
5959
return hasClassesNamed("com.azure.core.util.tracing.TracerProvider")
60-
// LibraryTelemetryOptions was introduced in azure-core 1.53
60+
// added in azure-core 1.53
6161
.and(not(hasClassesNamed("com.azure.core.util.LibraryTelemetryOptions")))
62-
// OpenTelemetryTracer was introduced in azure-core-tracing-opentelemetry 1.0.0-beta.47
62+
// added in azure-core-tracing-opentelemetry 1.0.0-beta.47 (native OTel support)
6363
.and(not(hasClassesNamed("com.azure.core.tracing.opentelemetry.OpenTelemetryTracer")));
6464
}
6565

instrumentation/azure-core/azure-core-1.53/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/azurecore/v1_53/AzureSdkInstrumentationModule.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ public void injectClasses(ClassInjector injector) {
5555

5656
@Override
5757
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
58-
// LibraryTelemetryOptions was introduced in azure-core 1.53
58+
// added in azure-core 1.53
5959
return hasClassesNamed("com.azure.core.util.LibraryTelemetryOptions")
60-
// OpenTelemetryTracer was introduced in azure-core-tracing-opentelemetry 1.0.0-beta.47
60+
// added in azure-core-tracing-opentelemetry 1.0.0-beta.47 (native OTel support)
6161
.and(not(hasClassesNamed("com.azure.core.tracing.opentelemetry.OpenTelemetryTracer")));
6262
}
6363

instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchApiClientInstrumentationModule.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,8 @@ public ElasticsearchApiClientInstrumentationModule() {
2525

2626
@Override
2727
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
28-
// Since Elasticsearch client version 8.10, the ES client comes with a native OTel
29-
// instrumentation
30-
// that introduced the class `co.elastic.clients.transport.instrumentation.Instrumentation`.
31-
// Disabling agent instrumentation for those cases.
3228
return hasClassesNamed(
33-
// present since 7.16 (base version of this instrumentation)
29+
// added in 7.16
3430
"co.elastic.clients.elasticsearch.ElasticsearchClient")
3531
// added in 8.10 (native OTel instrumentation)
3632
.and(not(hasClassesNamed("co.elastic.clients.transport.instrumentation.Instrumentation")));

instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,9 @@ public ElasticsearchRest7InstrumentationModule() {
2525

2626
@Override
2727
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
28-
// Class `org.elasticsearch.client.RestClient$InternalRequest` introduced in 7.0.0.
29-
// Since Elasticsearch client version 8.10, the ES client comes with a native OTel
30-
// instrumentation that introduced the class
31-
// `co.elastic.clients.transport.instrumentation.Instrumentation`.
32-
// Disabling agent instrumentation for those cases.
28+
// added in 7.0.0
3329
return hasClassesNamed("org.elasticsearch.client.RestClient$InternalRequest")
30+
// added in 8.10 (native OTel instrumentation)
3431
.and(not(hasClassesNamed("co.elastic.clients.transport.instrumentation.Instrumentation")));
3532
}
3633

instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-annotations/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrs/v2_0/JaxrsAnnotationsInstrumentationModule.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ public JaxrsAnnotationsInstrumentationModule() {
2626
// require jax-rs 2
2727
@Override
2828
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
29-
return hasClassesNamed(
30-
// added in 2.0
31-
"javax.ws.rs.core.Configurable");
29+
// added in 2.0
30+
return hasClassesNamed("javax.ws.rs.core.Configurable");
3231
}
3332

3433
@Override

instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrs/v2_0/Resteasy30InstrumentationModule.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
2525
return hasClassesNamed(
2626
// added in JAX-RS 2.0
2727
"javax.ws.rs.Path",
28-
// moved to jaxrs subpackage in 3.1.0, moved back in 3.5.0, moved again in 4.0.0
28+
// removed in 3.1.0.Final (moved to core.interception.jaxrs; back in 3.5.0; moved again in
29+
// 4.0.0)
2930
"org.jboss.resteasy.core.interception.PostMatchContainerRequestContext");
3031
}
3132

instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrs/v2_0/Resteasy31InstrumentationModule.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ public Resteasy31InstrumentationModule() {
2323
@Override
2424
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
2525
return hasClassesNamed(
26-
// present in JAX-RS 2.0+
26+
// added in JAX-RS 2.0
2727
"javax.ws.rs.Path",
28-
// added in RESTEasy 3.1.0.Final
28+
// added in RESTEasy 3.1.0.Final (moved from core.interception)
2929
"org.jboss.resteasy.core.interception.jaxrs.PostMatchContainerRequestContext");
3030
}
3131

0 commit comments

Comments
 (0)