From 6a35ea4a01a0be16e0beaf0bf078ff957dae76be Mon Sep 17 00:00:00 2001 From: arimu1 <19286898+arimu1@users.noreply.github.com> Date: Sat, 25 Jul 2026 23:17:26 +0700 Subject: [PATCH] fix(deps): make swagger-annotations compileOnly to avoid jakarta conflict Stop re-exporting javax swagger-annotations as an api dependency so consumers can use swagger-annotations-jakarta without split-package clashes. Register Swagger2Module only when Schema is on the classpath, and document that @Schema users must declare the annotation artifact. Fixes #796 --- README.md | 5 +++++ openai-java-core/build.gradle.kts | 6 +++++- .../kotlin/com/openai/core/StructuredOutputs.kt | 16 +++++++++++++--- openai-java-example/build.gradle.kts | 2 ++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 63157594d..8f3c356fc 100644 --- a/README.md +++ b/README.md @@ -795,6 +795,11 @@ annotations. These allow type-specific constraints to be added to your schema pr learn more about the supported constraints in the OpenAI documentation on [Supported properties](https://platform.openai.com/docs/guides/structured-outputs#supported-properties). +Add either `io.swagger.core.v3:swagger-annotations` or `io.swagger.core.v3:swagger-annotations-jakarta` +to your project yourself (the SDK no longer ships either as a transitive dependency, so javax and +Jakarta consumers do not conflict). Without one of those artifacts on the classpath, Swagger +annotations are ignored and Jackson annotations still work for schema generation. + ```java import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.ArraySchema; diff --git a/openai-java-core/build.gradle.kts b/openai-java-core/build.gradle.kts index f36399698..f2f4c8923 100644 --- a/openai-java-core/build.gradle.kts +++ b/openai-java-core/build.gradle.kts @@ -75,7 +75,10 @@ dependencies { api("com.fasterxml.jackson.core:jackson-core:$jacksonPublishedVersion") api("com.fasterxml.jackson.core:jackson-databind:$jacksonPublishedVersion") api("com.google.errorprone:error_prone_annotations:2.33.0") - api("io.swagger.core.v3:swagger-annotations:2.2.31") + // compileOnly: do not force javax swagger-annotations onto consumers. It conflicts with + // swagger-annotations-jakarta (same package). Consumers who use @Schema / @ArraySchema must + // declare either artifact themselves. See extractSchema() for optional Swagger2Module wiring. + compileOnly("io.swagger.core.v3:swagger-annotations:2.2.31") implementation("com.fasterxml.jackson.core:jackson-annotations:$jacksonPublishedVersion") implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:$jacksonPublishedVersion") @@ -88,6 +91,7 @@ dependencies { testImplementation(kotlin("test")) testImplementation(project(":openai-java-client-okhttp")) testImplementation(platform("com.fasterxml.jackson:jackson-bom:2.21.5")) + testImplementation("io.swagger.core.v3:swagger-annotations:2.2.31") testImplementation("org.assertj:assertj-core:3.27.7") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.3") diff --git a/openai-java-core/src/main/kotlin/com/openai/core/StructuredOutputs.kt b/openai-java-core/src/main/kotlin/com/openai/core/StructuredOutputs.kt index 36b3df529..2d4751391 100644 --- a/openai-java-core/src/main/kotlin/com/openai/core/StructuredOutputs.kt +++ b/openai-java-core/src/main/kotlin/com/openai/core/StructuredOutputs.kt @@ -203,9 +203,15 @@ internal fun extractSchema(type: Class<*>): ObjectNode { // Use `JacksonModule` to support the use of Jackson annotations to set property and // class names and descriptions and to mark fields with `@JsonIgnore`. .with(JacksonModule()) - // Use `Swagger2Module` to support OpenAPI Swagger 2 `@Schema` annotations to set - // property constraints (e.g., a `"pattern"` constraint for a string property). - .with(Swagger2Module()) + + // Swagger annotations are compileOnly (not a transitive dependency) so consumers can use + // either swagger-annotations or swagger-annotations-jakarta. Swagger2Module hard-references + // those classes; only register it when they are loadable on the consumer classpath. + if (isSwaggerAnnotationsPresent()) { + // Use `Swagger2Module` to support OpenAPI Swagger 2 `@Schema` annotations to set + // property constraints (e.g., a `"pattern"` constraint for a string property). + configBuilder.with(Swagger2Module()) + } configBuilder .forFields() @@ -218,6 +224,10 @@ internal fun extractSchema(type: Class<*>): ObjectNode { return SchemaGenerator(configBuilder.build()).generateSchema(type) } +/** True when javax or jakarta swagger-annotations are on the classpath (shared package). */ +private fun isSwaggerAnnotationsPresent(): Boolean = + runCatching { Class.forName("io.swagger.v3.oas.annotations.media.Schema") }.isSuccess + /** * Creates an instance of a Java class using data from a JSON string. The JSON data should conform * to the JSON schema previously extracted from the Java class. diff --git a/openai-java-example/build.gradle.kts b/openai-java-example/build.gradle.kts index 4644b2f91..1dc7207ca 100644 --- a/openai-java-example/build.gradle.kts +++ b/openai-java-example/build.gradle.kts @@ -10,6 +10,8 @@ repositories { dependencies { implementation(project(":openai-java")) implementation(project(":openai-java-bedrock")) + // Structured-output examples use @Schema / @ArraySchema; not transitive from openai-java-core. + implementation("io.swagger.core.v3:swagger-annotations:2.2.31") // Keep Azure Identity's Netty runtime aligned on a secure release. implementation(platform("io.netty:netty-bom:4.1.136.Final")) implementation("com.azure:azure-identity:1.18.4")