@Validated occasionally throws ConstraintDeclarationException from Hibernate Validator on JDK 15
See original GitHub issueSpring Boot 2.2.6, Spring Cloud Greenwich.RELEASE (I have since realized that I should be using the Hoxton branch with 2.2.x, which I have upgraded to now)
Following the suggestion from https://stackoverflow.com/questions/57811421/how-to-validate-request-parameters-on-feign-client/61635351#61635351, I can successfully use a validated Feign interface like this:
@Validated
@FeignClient( name = "gps-service", path = "${infrastructure.base-path.gps-service}" )
public interface GpsClient
{
@PostMapping( value = "/files/gpslogs" )
GpsLogFileResult triggerGpsLogFile( @RequestBody @Valid @NotNull GpsLogFileParameters parameters );
}
That is, this works most of the time. Very rarely, but then seemingly in bursts, the call to triggerGpsLogFile fails due to an exception like shown below. This application runs in a Kubernetes cluster and there are usually many thousands of calls to this method per day without the exception. Then one day, there are suddenly around 100 cases of the ConstraintDeclarationException within a time span of 10 minutes, only to be gone again afterwards.
javax.validation.ConstraintDeclarationException: HV000152: Two methods defined in parallel types must not declare parameter constraints, if they are overridden by the same method, but methods $Proxy268#triggerGpsLogFile(GpsLogFileParameters) and GpsClient#triggerGpsLogFile(GpsLogFileParameters) both define parameter constraints.
at org.hibernate.validator.internal.metadata.aggregated.rule.ParallelMethodsMustNotDefineParameterConstraints.apply(ParallelMethodsMustNotDefineParameterConstraints.java:23)
at org.hibernate.validator.internal.metadata.aggregated.ExecutableMetaData$Builder.assertCorrectnessOfConfiguration(ExecutableMetaData.java:461)
at org.hibernate.validator.internal.metadata.aggregated.ExecutableMetaData$Builder.build(ExecutableMetaData.java:377)
at org.hibernate.validator.internal.metadata.aggregated.BeanMetaDataImpl$BuilderDelegate.build(BeanMetaDataImpl.java:788)
at org.hibernate.validator.internal.metadata.aggregated.BeanMetaDataImpl$BeanMetaDataBuilder.build(BeanMetaDataImpl.java:648)
at org.hibernate.validator.internal.metadata.BeanMetaDataManager.createBeanMetaData(BeanMetaDataManager.java:204)
at org.hibernate.validator.internal.metadata.BeanMetaDataManager.getBeanMetaData(BeanMetaDataManager.java:166)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:265)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:233)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:105)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy269.triggerGpsLogFile(Unknown Source)
at com.acme.application.service.GpsService.triggerGpsLogFile(GpsService.java:227)
GpsService.triggerGpsLogFile() makes the call to GpsClient.triggerGpsLogFile().
Having read the relevant Hibernate Validator documentation and the source code of ParallelMethodsMustNotDefineParameterConstraints, I understand that Bean Validation method parameter annotations on overridden/implementing methods may pose a problem.
And as @wilkinsona pointed out at https://github.com/spring-projects/spring-boot/issues/17000, @Validated is realized by dynamic proxies (which can also be seen in the stacktrace above). So I kind of see why this could be a problem. But then I don’t understand why the vast majority of calls work correctly, also throwing a ConstraintViolationException (note: Violation <-> Declaration) if applicable.
I couldn’t find any official documentation about using @Validated on a @FeignClient, maybe that’s for a reason and what I’m doing is basically unsupported?
Issue Analytics
- State:
- Created 3 years ago
- Comments:13 (7 by maintainers)
Top Related StackOverflow Question
BTW here’s the Hibernate Validator ticket for it: https://hibernate.atlassian.net/browse/HV-1801?focusedCommentId=107317
Apparently there’s a workaround: adding the JVM flags
-XX:+UnlockDiagnosticVMOptions -XX:+ExpandSubTypeCheckAtParseTimeAfter debugging this down to the level of
Class.isAssignableFromin HV’sMethodConfigurationRule.isDefinedOnParallelTypehaving to misfunction in order for this to happen, it turns out that this is indeed a JVM bug that has been fixed for the yet-to-be-released JDK 15.0.2: https://bugs.openjdk.java.net/browse/JDK-8253566From that perspective, we won’t try to work around it in our code (and it seems we cannot anyway). Thanks for your help in narrowing this!