Open baoxingjie opened 1 month ago
That's right,
the sample you link to is using Spring Boot 2, i.e. javax
. Setting bean-validation: true
in the mapping.yaml
is the same as bean-validation: javax
.
For Spring Boot 3 you would use bean-validation: jakarta
.
Summary of the bean-validation
option: https://openapiprocessor.io/spring/processor/configuration.html#_bean_validation
The ..boot-3..
samples enable jakarta
bean-validation in their corresponding mapping.yaml
like this:
openapi-processor-mapping: v9
options:
package-name: io.openapiprocessor.samples
# use bean validations with jakarta package name
bean-validation: jakarta
Using:
openapi-processor-mapping: v9
options:
package-name: ro.btrl.opp
bean-validation: jakarta
with the Gradle plugin generates an error:
io.openapiprocessor.core.converter.InvalidMappingException: failed to parse 'mapping.yaml' configuration!
at io.openapiprocessor.core.converter.OptionsConverter.readMapping(OptionsConverter.kt:78)
at io.openapiprocessor.core.converter.OptionsConverter.convertOptions(OptionsConverter.kt:35)
at io.openapiprocessor.spring.processor.SpringProcessor.convertOptions(SpringProcessor.kt:112)
at io.openapiprocessor.spring.processor.SpringProcessor.run(SpringProcessor.kt:39)
at io.openapiprocessor.spring.processor.SpringService.run(SpringService.kt:29)
at io.openapiprocessor.gradle.OpenApiProcessorWorker.run(OpenApiProcessorWorker.java:108)
at io.openapiprocessor.gradle.OpenApiProcessorWorker.run(OpenApiProcessorWorker.java:57)
at io.openapiprocessor.gradle.OpenApiProcessorWorker.execute(OpenApiProcessorWorker.java:32)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:54)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:48)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:48)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:49)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:30)
at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.lambda$execute$0(IsolatedClassloaderWorkerFactory.java:57)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.execute(IsolatedClassloaderWorkerFactory.java:49)
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:174)
at java.base@17.0.11/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
at org.gradle.internal.Factories$1.create(Factories.java:31)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:263)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
at java.base@17.0.11/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base@17.0.11/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48)
at java.base@17.0.11/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base@17.0.11/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base@17.0.11/java.lang.Thread.run(Thread.java:840)
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `boolean` from String "jakarta": only "true"/"True"/"TRUE" or "false"/"False"/"FALSE" recognized
at [Source: (StringReader); line: 8, column: 20] (through reference chain: io.openapiprocessor.core.processor.mapping.v1.Mapping["options"]->io.openapiprocessor.core.processor.mapping.v1.Options["bean-validation"])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:2002)
at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:1230)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseBooleanPrimitive(StdDeserializer.java:451)
at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$BooleanDeserializer.deserialize(NumberDeserializers.java:225)
at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$BooleanDeserializer.deserialize(NumberDeserializers.java:200)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:545)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:568)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:439)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1409)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:352)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:545)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:568)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:439)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1409)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:352)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4825)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3772)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3740)
at io.openapiprocessor.core.processor.MappingReader.read(MappingReader.kt:72)
at io.openapiprocessor.core.converter.OptionsConverter.readMapping(OptionsConverter.kt:45)
... 44 more
Which version do you use? 2024.5?
From the callstack I can see that it is running into the wrong code path, i.e. it does not recognize the mapping version.
It looks like there is something wrong with the openapi-processor-mapping: v9
line...
I am using the gradle plugin:
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.5'
id 'io.spring.dependency-management' version '1.1.6'
id 'io.openapiprocessor.openapi-processor' version '2023.2'
}
From what I see, 2023.2 is the latest version for the plugin. Am I wrong?
I have fixed it by changing the processor version to 2024.5. I was previously trying to use 2023.2, just like the plugin version.
openapiProcessor {
spring {
processor 'io.openapiprocessor:openapi-processor-spring:2024.5'
apiPath "$projectDir/src/api/petstore3-adv.yaml"
targetDir "$projectDir/build/openapi"
mapping "$projectDir/src/openapi-processor/mapping.yaml"
parser "INTERNAL"
}
}
Thanks for the feedback that it works now. Yes the latest gradle plugin version is 2023.3.
latest spring version is 2024.6. I just asked for 2024.5 because the call stack includes code that does not exist anymore in 2024.6.
https://github.com/openapi-processor/openapi-processor-samples/blob/master/samples/spring-validation/gradle/libs.versions.toml
In Spring Boot 3.x, due to the migration of Jakarta EE to Jakarta Namespace, javax.validation has been replaced by jakarta.validation. As a result, by default, Spring Boot 3.x cannot directly use classes from the javax.validation package, such as javax.validation.ConstraintValidator and javax.validation.ConstraintValidatorContext. Their Jakarta equivalents are jakarta.validation.ConstraintValidator and jakarta.validation.ConstraintValidatorContext.