Skip to content

Commit ace934e

Browse files
committed
Fix NoClassDefFoundError when OTel SDK absent from classpath
When the OTel SDK jars are not on the application classpath, loading FlagEvalMetrics fails because field types reference OTel SDK classes (SdkMeterProvider). This propagated as an uncaught NoClassDefFoundError from the Provider constructor, crashing provider initialization. Fix: - Change meterProvider field type from SdkMeterProvider to Closeable (always on classpath), use local SdkMeterProvider variable inside try block - Catch NoClassDefFoundError in Provider constructor when creating FlagEvalMetrics - Null-safe getProviderHooks() and shutdown() when metrics is null
1 parent 9be3812 commit ace934e

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/FlagEvalMetrics.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ class FlagEvalMetrics implements Closeable {
3737
AttributeKey.stringKey("feature_flag.result.allocation_key");
3838

3939
private volatile LongCounter counter;
40-
private volatile SdkMeterProvider meterProvider;
40+
// Typed as Closeable to avoid loading SdkMeterProvider at class-load time
41+
// when the OTel SDK is absent from the classpath
42+
private volatile java.io.Closeable meterProvider;
4143

4244
FlagEvalMetrics() {
4345
try {
@@ -57,9 +59,11 @@ class FlagEvalMetrics implements Closeable {
5759
PeriodicMetricReader reader =
5860
PeriodicMetricReader.builder(exporter).setInterval(EXPORT_INTERVAL).build();
5961

60-
meterProvider = SdkMeterProvider.builder().registerMetricReader(reader).build();
62+
SdkMeterProvider sdkMeterProvider =
63+
SdkMeterProvider.builder().registerMetricReader(reader).build();
64+
meterProvider = sdkMeterProvider;
6165

62-
Meter meter = meterProvider.meterBuilder(METER_NAME).build();
66+
Meter meter = sdkMeterProvider.meterBuilder(METER_NAME).build();
6367
counter =
6468
meter
6569
.counterBuilder(METRIC_NAME)
@@ -113,7 +117,7 @@ public void close() {
113117

114118
void shutdown() {
115119
counter = null;
116-
SdkMeterProvider mp = meterProvider;
120+
java.io.Closeable mp = meterProvider;
117121
if (mp != null) {
118122
meterProvider = null;
119123
try {

products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/Provider.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,14 @@ public Provider(final Options options) {
4242
Provider(final Options options, final Evaluator evaluator) {
4343
this.options = options;
4444
this.evaluator = evaluator;
45-
this.flagEvalMetrics = new FlagEvalMetrics();
46-
this.flagEvalHook = new FlagEvalHook(flagEvalMetrics);
45+
FlagEvalMetrics metrics = null;
46+
try {
47+
metrics = new FlagEvalMetrics();
48+
} catch (NoClassDefFoundError | Exception e) {
49+
// OTel classes not on classpath — metrics disabled
50+
}
51+
this.flagEvalMetrics = metrics;
52+
this.flagEvalHook = new FlagEvalHook(metrics);
4753
}
4854

4955
@Override
@@ -86,12 +92,17 @@ private Evaluator buildEvaluator() throws Exception {
8692

8793
@Override
8894
public List<Hook> getProviderHooks() {
95+
if (flagEvalHook == null) {
96+
return Collections.emptyList();
97+
}
8998
return Collections.singletonList(flagEvalHook);
9099
}
91100

92101
@Override
93102
public void shutdown() {
94-
flagEvalMetrics.shutdown();
103+
if (flagEvalMetrics != null) {
104+
flagEvalMetrics.shutdown();
105+
}
95106
if (evaluator != null) {
96107
evaluator.shutdown();
97108
}

0 commit comments

Comments
 (0)