@@ -163,12 +163,19 @@ private byte[] generateMuzzleClass(InstrumenterModule module) {
163163 }
164164 }
165165
166+ ClassLoader contextClassLoader = Thread .currentThread ().getContextClassLoader ();
166167 String [] orderedHelpers =
167- discoverAndOrderHelpers (
168- seedHelpers ,
169- manualHelpers ,
170- helperPredicate ,
171- Thread .currentThread ().getContextClassLoader ());
168+ discoverAndOrderHelpers (seedHelpers , manualHelpers , helperPredicate , contextClassLoader );
169+
170+ // Drop build-time-only muzzle providers
171+ ClassFileLocator locator = ClassFileLocator .ForClassLoader .of (contextClassLoader );
172+ List <String > injectableHelpers = new ArrayList <>(orderedHelpers .length );
173+ for (String helper : orderedHelpers ) {
174+ if (!isBuildTimeOnly (helper , locator )) {
175+ injectableHelpers .add (helper );
176+ }
177+ }
178+ orderedHelpers = injectableHelpers .toArray (new String [0 ]);
172179
173180 writeInferenceReport (module , adviceClasses .isEmpty (), inferredHelpers , orderedHelpers );
174181
@@ -278,6 +285,26 @@ private void addNestedClasses(String className, Set<String> helperClasses) {
278285 }
279286 }
280287
288+ private static final String MUZZLE_REFERENCE_API = "datadog/trace/agent/tooling/muzzle/Reference" ;
289+
290+ /**
291+ * {@code true} if the class uses the muzzle {@link Reference} API (as a {@link ReferenceProvider}
292+ * or via {@code compileReferences}). Use this method to avoid injecting build-time-only classes.
293+ */
294+ private static boolean isBuildTimeOnly (String className , ClassFileLocator locator ) {
295+ try {
296+ ClassFileLocator .Resolution resolution = locator .locate (className );
297+ if (!resolution .isResolved ()) {
298+ return false ;
299+ }
300+ // The muzzle type appears as a constant-pool entry when the class references it.
301+ return new String (resolution .resolve (), StandardCharsets .ISO_8859_1 )
302+ .contains (MUZZLE_REFERENCE_API );
303+ } catch (IOException e ) {
304+ return false ;
305+ }
306+ }
307+
281308 /**
282309 * Runs {@link HelperScanner} over the seed helpers to both discover their transitive helper
283310 * dependencies and load-order the result (dependencies first). Keeps only our own helpers (plus
0 commit comments