@Validated occasionally throws ConstraintDeclarationException from Hibernate Validator on JDK 15

See original GitHub issue

Spring 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:closed
  • Created 3 years ago
  • Comments:13 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
jhoellercommented, Dec 4, 2020

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:+ExpandSubTypeCheckAtParseTime

2reactions
jhoellercommented, Dec 3, 2020

After debugging this down to the level of Class.isAssignableFrom in HV’s MethodConfigurationRule.isDefinedOnParallelType having 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-8253566

From 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!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Hibernate Validator 8.0.0.Final - Jakarta Bean Validation ...
Validating data is a common task that occurs throughout all application layers, from the presentation to the persistence layer.
Read more >
How to avoid Hibernate Validator ...
So I put Bean Validation constraints on the implementation and it forces me to put that constraints on the interface (throwing ...
Read more >
Validation with Hibernate Validator - Quarkus
This guide covers how to use Hibernate Validator/Bean Validation for: validating the input/output of your REST services; validating the parameters and return ...
Read more >
[HV-1801] Hibernate Validation fails with JDK15
Sometime we will get the wrong result and a ConstraintDeclarationException is thrown. I checked that all use same classloader. This also happen with...
Read more >
Jakarta Bean Validation specification - Jakarta® EE
1.5. Constraint specific parameter. The constraint annotation definitions may define additional elements to parameterize the constraint. For ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found