Skip to content

Commit f1d4b40

Browse files
committed
Fix GraalVM smoke test on Java 21
The root issue was that the reference to MemFDUnixWriter in the TracerInstaller bytecode was being picked up by HelperScanner, which is a utility that we use to avoid having to maintain an exact list of classes to inject into GraalVM in order to activate the tracer in the final native binary via VMRuntimeInstrumentation and TracerActivation. The simplest solution was to use reflection to load MemFDUnixWriter. The alternative would have been to enhance HelperScanner to be able to exclude types from the list of classes it finds. However this would be more complicated.
1 parent 06e9f16 commit f1d4b40

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/TracerInstaller.java

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
import datadog.communication.ddagent.SharedCommunicationObjects;
44
import datadog.environment.OperatingSystem;
5-
import datadog.trace.agent.tooling.servicediscovery.MemFDUnixWriter;
65
import datadog.trace.api.Config;
76
import datadog.trace.api.GlobalTracer;
87
import datadog.trace.api.Platform;
98
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
109
import datadog.trace.bootstrap.instrumentation.api.ProfilingContextIntegration;
1110
import datadog.trace.core.CoreTracer;
11+
import datadog.trace.core.CoreTracer.CoreTracerBuilder;
12+
import datadog.trace.core.servicediscovery.ForeignMemoryWriter;
1213
import datadog.trace.core.servicediscovery.ServiceDiscovery;
1314
import org.slf4j.Logger;
1415
import org.slf4j.LoggerFactory;
@@ -21,15 +22,16 @@ public static synchronized void installGlobalTracer(
2122
ProfilingContextIntegration profilingContextIntegration) {
2223
if (Config.get().isTraceEnabled() || Config.get().isCiVisibilityEnabled()) {
2324
if (!(GlobalTracer.get() instanceof CoreTracer)) {
24-
CoreTracer tracer =
25+
CoreTracerBuilder tracerBuilder =
2526
CoreTracer.builder()
2627
.sharedCommunicationObjects(sharedCommunicationObjects)
2728
.profilingContextIntegration(profilingContextIntegration)
2829
.reportInTracerFlare()
29-
.pollForTracingConfiguration()
30-
.serviceDiscovery(getServiceDiscovery())
31-
.build();
32-
installGlobalTracer(tracer);
30+
.pollForTracingConfiguration();
31+
32+
maybeEnableServiceDiscovery(tracerBuilder);
33+
34+
installGlobalTracer(tracerBuilder.build());
3335
} else {
3436
log.debug("GlobalTracer already registered.");
3537
}
@@ -38,17 +40,26 @@ public static synchronized void installGlobalTracer(
3840
}
3941
}
4042

41-
private static ServiceDiscovery getServiceDiscovery() {
43+
private static void maybeEnableServiceDiscovery(CoreTracerBuilder tracerBuilder) {
4244
if (!OperatingSystem.isLinux()) {
4345
log.debug("service discovery not supported outside linux");
44-
return null;
46+
return;
4547
}
4648
// make sure this branch is not considered possible for graalvm artifact
47-
if (!Platform.isNativeImageBuilder() && !Platform.isNativeImage()) {
48-
return new ServiceDiscovery(new MemFDUnixWriter());
49+
if (Platform.isNativeImageBuilder()) {
50+
log.debug("service discovery not supported on native images");
51+
return;
52+
}
53+
try {
54+
// use reflection to load MemFDUnixWriter so it doesn't get picked up when we transitively
55+
// look for all tracer class dependencies to install in GraalVM via VMRuntimeInstrumentation
56+
Class<?> memFdClass =
57+
Class.forName("datadog.trace.agent.tooling.servicediscovery.MemFDUnixWriter");
58+
ForeignMemoryWriter memFd = (ForeignMemoryWriter) memFdClass.getConstructor().newInstance();
59+
tracerBuilder.serviceDiscovery(new ServiceDiscovery(memFd));
60+
} catch (Throwable e) {
61+
log.debug("service discovery not supported", e);
4962
}
50-
log.debug("service discovery not supported on native images");
51-
return null;
5263
}
5364

5465
public static void installGlobalTracer(final CoreTracer tracer) {

0 commit comments

Comments
 (0)