Files
langsmith-java/langsmith-java-example/build.gradle.kts
T
John Kennedy 8b1dff9a1e fix: patch 6 high-severity security alerts (#42)
## Security Alert Patch

Resolves all 6 open high-severity Dependabot alerts in the Maven
dependency graph.

### Packages Updated

| Package | Resolved change | Strategy | Scope | CVEs resolved |
|---|---|---|---|---|
| com.fasterxml.jackson.core:jackson-databind | 2.15.3 -> 2.18.8; 2.21.0
-> 2.21.4 | Parent bump for Palantir plus constrained Dokka classpaths |
Build/dev only | CVE-2026-54512, CVE-2026-54513 |
| org.bouncycastle:bcpg-jdk18on | 1.80 -> 1.84 | Constraint on Kotlin
publishing validation | Build/dev only | CVE-2026-3505 |
| org.codehaus.plexus:plexus-utils | 4.0.2 -> 4.0.3 | Constraint on
Shadow plugin classpath | Test/build only | CVE-2025-67030 |

### Strategy Notes

- Palantir Java Format moves from 2.89.0 to 2.93.0, the first release
that declares patched Jackson 2.21.4.
- Dokka 2.2.0 is the latest release and still declares Jackson 2.15.3,
so its buildscript and worker configurations are constrained to 2.18.8.
Remove the constraint when Dokka publishes a patched dependency graph.
- Kotlin publishing validation selects Bouncy Castle 1.80 internally, so
that isolated configuration is constrained to 1.84.
- Shadow 8.3.8 still declares Plexus Utils 4.0.2. Shadow 9.4.3 was
assessed but failed the repository R8 compatibility test, so the plugin
remains at 8.3.8 with a buildscript-only Plexus constraint.

### Advisory Details

- CVE-2026-54512 / GHSA-j3rv-43j4-c7qm: Jackson polymorphic type
validator bypass via generic type parameters.
- CVE-2026-54513 / GHSA-rmj7-2vxq-3g9f: Jackson array subtype allowlist
bypass.
- CVE-2026-3505 / GHSA-cj8j-37rh-8475: Bouncy Castle uncontrolled
resource consumption.
- CVE-2025-67030 / GHSA-6fmv-xxpf-w3cw: Plexus Utils directory traversal
in extractFile.

### Linear Tickets

No matching open Linear tickets found.

### Verification

- [x] All project dependency reports contain no affected vulnerable
versions
- [x] Kotlin and Java lint pass
- [x] Full Gradle test suite passes
- [x] ProGuard and R8 compatibility checks pass
- [x] Dokka Javadoc generation passes
- [x] git diff --check passes
2026-07-16 11:55:45 +02:00

101 lines
3.8 KiB
Kotlin

plugins {
application
kotlin("jvm")
id("org.jetbrains.kotlin.plugin.spring") version "2.1.20"
id("org.springframework.boot") version "3.5.16" apply false
}
repositories {
mavenCentral()
}
configurations.configureEach {
// CVE-2026-10532: remove once the Spring Boot BOM manages Logback >= 1.5.35.
resolutionStrategy.force(
"ch.qos.logback:logback-classic:1.5.35",
"ch.qos.logback:logback-core:1.5.35",
)
}
// Align with Kotlin JVM target (Kotlin plugin applies Java plugin; keep targets consistent)
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
dependencies {
implementation(project(":langsmith-java"))
implementation(kotlin("stdlib"))
// Jackson for JSON handling in examples
implementation("com.fasterxml.jackson.core:jackson-databind:2.22.1")
// Spring Boot dependencies (optional - only needed for Spring Boot example)
implementation(platform("org.springframework.boot:spring-boot-dependencies:3.5.16"))
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter")
// Simple logging for examples. This lets smoke tests show SDK debug/trace logs.
runtimeOnly("org.slf4j:slf4j-simple:2.0.17")
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
}
}
application {
// Require -Pexample=Name to run an example (e.g. -Pexample=ListRuns, -Pexample=OtelLangSmith)
mainClass = if (project.hasProperty("example")) {
var exampleName = project.property("example") as String
val aliases = mapOf(
"OtelLangSmithSimple" to "OtelLangSmith",
"PromptManagmentExample" to "PromptManagement",
"PromptManagment" to "PromptManagement",
)
exampleName = aliases[exampleName] ?: exampleName
val baseName = if (exampleName.endsWith("Example")) exampleName else "${exampleName}Example"
val searchPaths = listOf(
"" to "com.langchain.smith.example",
"otel/" to "com.langchain.smith.example.otel"
)
var foundPackage = ""
for ((subdir, packageName) in searchPaths) {
val kotlinFile = file("src/main/kotlin/com/langchain/smith/example/${subdir}${baseName}.kt")
if (kotlinFile.exists()) {
foundPackage = packageName
break
}
}
if (foundPackage.isNotEmpty()) {
"${foundPackage}.${baseName}Kt"
} else {
throw GradleException(
"Example '$exampleName' not found. No ${baseName}.kt in " +
"src/main/kotlin/.../example/ or .../example/otel/. " +
"Use -Pexample=ListRuns, -Pexample=OtelLangSmith, -Pexample=OtelLangSmithSimple, -Pexample=OtelOpenAI, etc."
)
}
} else {
"Main" // placeholder; run task doFirst will require -Pexample=
}
}
// Export stdin to examples for readln(); require -Pexample= when running (configuration-cache safe: no project access in doFirst)
tasks.named<JavaExec>("run") {
standardInput = System.`in`
systemProperty("org.slf4j.simpleLogger.defaultLogLevel", "info")
systemProperty("org.slf4j.simpleLogger.log.com.langchain.smith.client.AutoBatchQueue", "trace")
systemProperty("org.slf4j.simpleLogger.showDateTime", "false")
systemProperty("org.slf4j.simpleLogger.showShortLogName", "true")
doFirst {
if (mainClass.get() == "Main") {
throw GradleException(
"Example module requires -Pexample=ExampleName. " +
"e.g. ./gradlew :langsmith-java-example:run -Pexample=ListRuns"
)
}
}
}