Skip to content

Commit ac2dbbf

Browse files
feat: add a main class for jar build sanity checking
Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <aider@aider.chat>
1 parent 1002b8e commit ac2dbbf

3 files changed

Lines changed: 59 additions & 21 deletions

File tree

build.gradle

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ jar {
192192
attributes(
193193
'Implementation-Title': 'Braintrust Java SDK',
194194
'Implementation-Version': version,
195-
'Implementation-Vendor': 'Braintrust'
195+
'Implementation-Vendor': 'Braintrust',
196+
'Main-Class': 'dev.braintrust.trace.SDKMain'
196197
)
197198
}
198199
}
@@ -273,14 +274,30 @@ task validateJavaVersion {
273274
"from ${System.getProperty('java.home')}"
274275
)
275276
}
277+
// println "✓ Using Java ${currentVersion} from ${System.getProperty('java.home')}"
278+
}
279+
}
280+
281+
282+
// Task to test the jar by running it
283+
task testJar(type: Exec) {
284+
description = 'Test the jar by running it and fail build if non-zero exit code'
285+
group = 'verification'
286+
dependsOn jar
276287

277-
println "✓ Using Java ${currentVersion} from ${System.getProperty('java.home')}"
288+
commandLine 'java', '-jar', jar.archiveFile.get().asFile.absolutePath
289+
290+
doFirst {
291+
// println "Testing jar: ${jar.archiveFile.get().asFile.absolutePath}"
278292
}
279293
}
280294

281295
// Run validation before compilation
282296
compileJava.dependsOn validateJavaVersion
283297

298+
// Run jar test as part of check task
299+
check.dependsOn testJar
300+
284301
// Task to install git hooks
285302
task installGitHooks(type: Exec) {
286303
description = 'Install git hooks for code formatting'

src/main/java/dev/braintrust/trace/BraintrustTracing.java

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
1818
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
1919
import java.time.Duration;
20-
import java.util.Properties;
2120
import java.util.concurrent.TimeUnit;
2221
import java.util.stream.Stream;
2322
import javax.annotation.Nonnull;
@@ -32,7 +31,7 @@ public final class BraintrustTracing {
3231
public static final String PARENT_KEY = "braintrust.parent";
3332
static final String OTEL_SERVICE_NAME = "braintrust-app";
3433
static final String INSTRUMENTATION_NAME = "braintrust-java";
35-
static final String INSTRUMENTATION_VERSION = loadVersionFromProperties();
34+
static final String INSTRUMENTATION_VERSION = SDKMain.loadVersionFromProperties();
3635

3736
/**
3837
* Quick start method that sets up global OpenTelemetry with Braintrust defaults. <br>
@@ -88,15 +87,7 @@ public static void enable(
8887
final Duration exportInterval = Duration.ofSeconds(5);
8988
final int maxQueueSize = 2048;
9089
final int maxExportBatchSize = 512;
91-
log.info(
92-
"Initializing Braintrust OpenTelemetry with service={}, instrumentation-name={},"
93-
+ " instrumentation-version={}, jvm-version={}, jvm-vendor={}, jvm-name={}",
94-
OTEL_SERVICE_NAME,
95-
INSTRUMENTATION_NAME,
96-
INSTRUMENTATION_VERSION,
97-
System.getProperty("java.runtime.version"),
98-
System.getProperty("java.vendor"),
99-
System.getProperty("java.vm.name"));
90+
log.info(sdkInfoLogMessage());
10091

10192
// Create resource first so BraintrustSpanProcessor can access service.name
10293
var resourceBuilder =
@@ -164,14 +155,15 @@ public static Tracer getTracer(OpenTelemetry openTelemetry) {
164155
return openTelemetry.getTracer(INSTRUMENTATION_NAME, INSTRUMENTATION_VERSION);
165156
}
166157

167-
private static String loadVersionFromProperties() {
168-
try (var is = BraintrustTracing.class.getResourceAsStream("/braintrust.properties")) {
169-
var props = new Properties();
170-
props.load(is);
171-
return props.getProperty("sdk.version");
172-
} catch (Exception e) {
173-
throw new RuntimeException("unable to determine sdk version", e);
174-
}
158+
private static String sdkInfoLogMessage() {
159+
return "Initializing Braintrust OpenTelemetry with service=%s, instrumentation-name=%s, instrumentation-version=%s, jvm-version=%s, jvm-vendor=%s, jvm-name=%s"
160+
.formatted(
161+
OTEL_SERVICE_NAME,
162+
INSTRUMENTATION_NAME,
163+
INSTRUMENTATION_VERSION,
164+
System.getProperty("java.runtime.version"),
165+
System.getProperty("java.vendor"),
166+
System.getProperty("java.vm.name"));
175167
}
176168

177169
private BraintrustTracing() {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package dev.braintrust.trace;
2+
3+
import java.util.Properties;
4+
5+
class SDKMain {
6+
/**
7+
* Called by the build system to verify internals of the SDK. Prints sdk version to stdout.
8+
*
9+
* <p>Be mindful of classloading here. Otel is not shipped in the jar, so referencing otel
10+
* classes directly or indirectly will fail the build with a NoClassDefFound error.
11+
*/
12+
public static void main(String... args) {
13+
var sdkVersion = loadVersionFromProperties();
14+
if (null == sdkVersion || sdkVersion.isEmpty()) {
15+
throw new RuntimeException("sdk version not found: %s".formatted(sdkVersion));
16+
}
17+
System.out.println(sdkVersion);
18+
}
19+
20+
static String loadVersionFromProperties() {
21+
try (var is = SDKMain.class.getResourceAsStream("/braintrust.properties")) {
22+
var props = new Properties();
23+
props.load(is);
24+
return props.getProperty("sdk.version");
25+
} catch (Exception e) {
26+
throw new RuntimeException("unable to determine sdk version", e);
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)