Closed
Description
Andy Wilkinson opened SPR-15629 and commented
In exploring a possible fix for this Spring Boot issue I've hit a problem when MethodValidationPostProcessor
is configured with a CustomValidatorBean
that's @Lazy
. This small sample reproduces the problem with Spring Framework 4.3.8.RELEASE and Hibernate Validator 5.3:
package com.example;
import javax.validation.Validator;
import javax.validation.constraints.Size;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.annotation.Validated;
import org.springframework.validation.beanvalidation.CustomValidatorBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
public class LazyValidatorProblem {
@Configuration
static class ValidatorConfiguration {
@Bean
public Validator customValidator() {
return new CustomValidatorBean();
}
}
@Configuration
static class BeanPostProcessorConfiguration {
@Bean
public static MethodValidationPostProcessor methodValidationPostProcessor(
@Lazy Validator validator) {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
postProcessor.setValidator(validator);
return postProcessor;
}
}
@Configuration
static class ServiceConfiguration {
@Bean
public SampleService sampleService() {
return new SampleService();
}
}
@Validated
static class SampleService {
public void doSomething(@Size(min = 3, max = 10) String name) {
}
}
public static void main(String[] args) {
new AnnotationConfigApplicationContext(ValidatorConfiguration.class,
BeanPostProcessorConfiguration.class, ServiceConfiguration.class)
.getBean(SampleService.class).doSomething("testing");
}
}
The failure that you should see is:
Exception in thread "main" java.lang.AbstractMethodError: org.springframework.validation.beanvalidation.CustomValidatorBean.forExecutables()Ljavax/validation/executable/ExecutableValidator;
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy9.forExecutables(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:216)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:201)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.example.LazyValidatorProblem$SampleService$$EnhancerBySpringCGLIB$$d8a8543a.doSomething(<generated>)
at com.example.LazyValidatorProblem.main(LazyValidatorProblem.java:58)
This happens because SpringValidatorAdapter
does not implement the forExecutables
method that was added to Validator
in Bean Validation 1.1. The problem does not occur with Spring Framework 5.0 as a result of this commit.
Affects: 4.3.8
Reference URL: spring-projects/spring-boot#9416
Issue Links:
- LocalValidatorFactoryBean does not support unwrap for native ValidatorFactory [SPR-15561] #20120 LocalValidatorFactoryBean does not support unwrap for native ValidatorFactory
- Follow-up: AbstractMethodError when calling validated method of MethodValidationPostProcessor is using a @Lazy validator [SPR-15807] #20362 Follow-up: AbstractMethodError when calling validated method of MethodValidationPostProcessor is using a
@Lazy
validator