Add Jakarta validation module in JSON schema generator#6541
Add Jakarta validation module in JSON schema generator#6541nicolaskrier wants to merge 1 commit into
Conversation
|
|
||
| <dependency> | ||
| <groupId>jakarta.validation</groupId> | ||
| <artifactId>jakarta.validation-api</artifactId> |
There was a problem hiding this comment.
Shouldn't this be scope=test?
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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>
5baec37 to
54ad520
Compare
No description provided.