Skip to content

Add Jakarta validation module in JSON schema generator#6541

Open
nicolaskrier wants to merge 1 commit into
spring-projects:mainfrom
nicolaskrier:json-schema-generator-with-jakarta-validation
Open

Add Jakarta validation module in JSON schema generator#6541
nicolaskrier wants to merge 1 commit into
spring-projects:mainfrom
nicolaskrier:json-schema-generator-with-jakarta-validation

Conversation

@nicolaskrier

Copy link
Copy Markdown
Contributor

No description provided.

Comment thread spring-ai-model/pom.xml

<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be scope=test?

@nicolaskrier nicolaskrier Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I had asked myself a similar question initially but I thought it was fine to add it directly like io.swagger.core.v3:swagger-annotations-jakarta dependency with Victools Swagger 2 module dependency, com.github.victools:jsonschema-module-swagger-2.

On top of that, there is an issue if this dependency is not in the classpath because it is required by JakartaValidationModule at runtime. I got the following exception while running org.springframework.ai.chat.client.advisor.StructuredOutputValidationAdvisorTests unit tests without this dependency in the classpath:

java.lang.NoClassDefFoundError: Could not initialize class org.springframework.ai.util.json.schema.JsonSchemaGenerator

	at org.springframework.ai.chat.client.advisor.StructuredOutputValidationAdvisor$Builder.build(StructuredOutputValidationAdvisor.java:353)
	at org.springframework.ai.chat.client.advisor.StructuredOutputValidationAdvisorTests.testBuilderMethodChainingWithJacksonTypeReference(StructuredOutputValidationAdvisorTests.java:123)
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.NoClassDefFoundError: jakarta/validation/constraints/AssertFalse [in thread "main"]
	at com.github.victools.jsonschema.module.jakarta.validation.JakartaValidationModule.applyToConfigBuilder(JakartaValidationModule.java:121)
	at com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder.with(SchemaGeneratorConfigBuilder.java:226)
	at org.springframework.ai.util.json.schema.JsonSchemaGenerator.<clinit>(JsonSchemaGenerator.java:110)
	at org.springframework.ai.chat.client.advisor.StructuredOutputValidationAdvisor$Builder.build(StructuredOutputValidationAdvisor.java:353)
	at org.springframework.ai.chat.client.advisor.StructuredOutputValidationAdvisorTests.lambda$whenAdvisorOrderIsOutOfRangeThenThrow$2(StructuredOutputValidationAdvisorTests.java:97)
	at org.assertj.core.api.ThrowableAssert.catchThrowable(ThrowableAssert.java:66)
	at org.assertj.core.api.AssertionsForClassTypes.catchThrowable(AssertionsForClassTypes.java:908)
	at org.assertj.core.api.Assertions.catchThrowable(Assertions.java:1476)
	at org.assertj.core.api.Assertions.assertThatThrownBy(Assertions.java:1319)
	at org.springframework.ai.chat.client.advisor.StructuredOutputValidationAdvisorTests.whenAdvisorOrderIsOutOfRangeThenThrow(StructuredOutputValidationAdvisorTests.java:96)

We could consider using reflection to enable JakartaValidationModule module only if jakarta.validation.Constraint annotation is in the classpath. Also, I prefer using optional flag for Jakarta Validation API dependency because I think it will guide Spring AI users about this potential use case scenario. I believe it also something to add in the documentation if we opt for this optional dependency solution.

What do you think about all of this?

Module openApiModule = new Swagger2Module();
Module springAiSchemaModule = PROPERTY_REQUIRED_BY_DEFAULT ? new SpringAiSchemaModule()
: new SpringAiSchemaModule(SpringAiSchemaModule.Option.PROPERTY_REQUIRED_FALSE_BY_DEFAULT);
Module jakartaValidationModule = new JakartaValidationModule();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module proposes two different options:

  • JakartaValidationOption.NOT_NULLABLE_FIELD_IS_REQUIRED,
  • JakartaValidationOption.NOT_NULLABLE_METHOD_IS_REQUIRED.

These options are not necessary here because PROPERTY_REQUIRED_BY_DEFAULT value is true. Nevertheless, I verified the correctness of the behavior of these options by using them while instantiating JakartaValidationModule and setting PROPERTY_REQUIRED_BY_DEFAULT value to false.

Signed-off-by: Nicolas Krier <7557886+nicolaskrier@users.noreply.github.com>
@nicolaskrier nicolaskrier force-pushed the json-schema-generator-with-jakarta-validation branch from 5baec37 to 54ad520 Compare July 4, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants