Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,28 @@ private void recordInstrumentationProgress(
}

private void retransformClasses(List<Class<?>> classesToBeTransformed) {
int classCount = classesToBeTransformed.size();
if (classCount <= 10) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why 10? What the benefit here?

Copy link
Member Author

@jpbempel jpbempel Jan 5, 2026

Choose a reason for hiding this comment

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

if a retransformation fails it is easier to pinpoint which class is failing that way (individually). here we consider that if we have more than 10 the classes belong to same "family" (here the inner classes).

retransformIndividualClasses(classesToBeTransformed);
} else if (classCount <= 1000) {
retransformClassesAtOnce(classesToBeTransformed);
} else {
throw new IllegalStateException("Too many classes to retransform: " + classCount);
Copy link
Member

Choose a reason for hiding this comment

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

What happens from the users perspective when there are more than 1,000 classes to transform? Is this raised as an instrumentation error?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes

}
}

private void retransformClassesAtOnce(List<Class<?>> classesToBeTransformed) {
LOGGER.debug("Re-transforming classes: {}", classesToBeTransformed);
try {
instrumentation.retransformClasses(classesToBeTransformed.toArray(new Class[0]));
} catch (Exception ex) {
ExceptionHelper.logException(LOGGER, ex, "Re-transform error:");
} catch (Throwable ex) {
ExceptionHelper.logException(LOGGER, ex, "Re-transform throwable:");
}
}

private void retransformIndividualClasses(List<Class<?>> classesToBeTransformed) {
for (Class<?> clazz : classesToBeTransformed) {
try {
LOGGER.debug("Re-transforming class: {}", clazz.getTypeName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.datadog.debugger.probe.LogProbe;
import com.datadog.debugger.probe.ProbeDefinition;
import datadog.trace.bootstrap.debugger.ProbeId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -407,6 +408,22 @@ public void allLoadedChangedClassesTopLevelClassSimpleFileName() {
probe, sourceFileMapping, MyTopLevelClass.class, false, MyTopLevelClass.class);
}

@Test
public void allLoadedChangedClassesLargeInnerClasses() {
final String CLASS_FILENAME = "LargeInnerClasses.java";
Map<String, List<String>> sourceFileMapping = new HashMap<>();
List<String> classNames = new ArrayList<>();
for (int i = 0; i < 100; i++) {
classNames.add(
String.format("com.datadog.debugger.agent.LargeInnerClasses$MyInnerClass%02d", i));
}
sourceFileMapping.put(CLASS_FILENAME, classNames);
LogProbe probe =
LogProbe.builder().probeId(PROBE_ID).where(null, null, null, 6, CLASS_FILENAME).build();
doAllLoadedChangedClasses(
probe, sourceFileMapping, LargeInnerClasses.class, false, LargeInnerClasses.class);
}

private void doAllLoadedChangedClasses(
LogProbe probe,
Map<String, List<String>> sourceFileMapping,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package com.datadog.debugger.agent;

public class LargeInnerClasses {

public static int main(String arg) {
return 42; // beae1817-f3b0-4ea8-a74f-000000000001
}

static class MyInnerClass00 {}

static class MyInnerClass01 {}

static class MyInnerClass02 {}

static class MyInnerClass03 {}

static class MyInnerClass04 {}

static class MyInnerClass05 {}

static class MyInnerClass06 {}

static class MyInnerClass07 {}

static class MyInnerClass08 {}

static class MyInnerClass09 {}

static class MyInnerClass10 {}

static class MyInnerClass11 {}

static class MyInnerClass12 {}

static class MyInnerClass13 {}

static class MyInnerClass14 {}

static class MyInnerClass15 {}

static class MyInnerClass16 {}

static class MyInnerClass17 {}

static class MyInnerClass18 {}

static class MyInnerClass19 {}

static class MyInnerClass20 {}

static class MyInnerClass21 {}

static class MyInnerClass22 {}

static class MyInnerClass23 {}

static class MyInnerClass24 {}

static class MyInnerClass25 {}

static class MyInnerClass26 {}

static class MyInnerClass27 {}

static class MyInnerClass28 {}

static class MyInnerClass29 {}

static class MyInnerClass30 {}

static class MyInnerClass31 {}

static class MyInnerClass32 {}

static class MyInnerClass33 {}

static class MyInnerClass34 {}

static class MyInnerClass35 {}

static class MyInnerClass36 {}

static class MyInnerClass37 {}

static class MyInnerClass38 {}

static class MyInnerClass39 {}

static class MyInnerClass40 {}

static class MyInnerClass41 {}

static class MyInnerClass42 {}

static class MyInnerClass43 {}

static class MyInnerClass44 {}

static class MyInnerClass45 {}

static class MyInnerClass46 {}

static class MyInnerClass47 {}

static class MyInnerClass48 {}

static class MyInnerClass49 {}

static class MyInnerClass50 {}

static class MyInnerClass51 {}

static class MyInnerClass52 {}

static class MyInnerClass53 {}

static class MyInnerClass54 {}

static class MyInnerClass55 {}

static class MyInnerClass56 {}

static class MyInnerClass57 {}

static class MyInnerClass58 {}

static class MyInnerClass59 {}

static class MyInnerClass60 {}

static class MyInnerClass61 {}

static class MyInnerClass62 {}

static class MyInnerClass63 {}

static class MyInnerClass64 {}

static class MyInnerClass65 {}

static class MyInnerClass66 {}

static class MyInnerClass67 {}

static class MyInnerClass68 {}

static class MyInnerClass69 {}

static class MyInnerClass70 {}

static class MyInnerClass71 {}

static class MyInnerClass72 {}

static class MyInnerClass73 {}

static class MyInnerClass74 {}

static class MyInnerClass75 {}

static class MyInnerClass76 {}

static class MyInnerClass77 {}

static class MyInnerClass78 {}

static class MyInnerClass79 {}

static class MyInnerClass80 {}

static class MyInnerClass81 {}

static class MyInnerClass82 {}

static class MyInnerClass83 {}

static class MyInnerClass84 {}

static class MyInnerClass85 {}

static class MyInnerClass86 {}

static class MyInnerClass87 {}

static class MyInnerClass88 {}

static class MyInnerClass89 {}

static class MyInnerClass90 {}

static class MyInnerClass91 {}

static class MyInnerClass92 {}

static class MyInnerClass93 {}

static class MyInnerClass94 {}

static class MyInnerClass95 {}

static class MyInnerClass96 {}

static class MyInnerClass97 {}

static class MyInnerClass98 {}

static class MyInnerClass99 {}
}
Loading
Loading