GianMaria Romanato created BVAL-158:
---------------------------------------

             Summary: ExecutableValidator invokes method if it looks like a 
getter
                 Key: BVAL-158
                 URL: https://issues.apache.org/jira/browse/BVAL-158
             Project: BVal
          Issue Type: Bug
          Components: method validation
    Affects Versions: 1.1.2
            Reporter: GianMaria Romanato


When ExecutableValidator is used to validate the input parameters of a method 
that:
 * has no input parameters
 * returns a value that is annotated @Valid
 * is named  "get"-something

the implementation of the validator seems to assume that the method is a getter 
for a property, and even if the user code has only invoked 
ExecutableValidator.validateParameters() the validator decides to apply 
cascaded validation and invokes the given method to obtain the return value and 
validate it.

This behaviour can be demonstrated by the following snippet which results in 
the RuntimeException being raised by the validation.
{code:java}
public class BValTest {
    
    public static void main(String[] args) throws NoSuchMethodException, 
SecurityException {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        javax.validation.Validator validator = factory.getValidator();
        ExecutableValidator methodValidator = validator.forExecutables();
        
        BValTest p = new BValTest();
        Method method = p.getClass().getDeclaredMethod("getAll", null);
        
        Set<ConstraintViolation<BValTest>> result = 
methodValidator.validateParameters(p, method, new Object[0]);
        System.out.println("Success");
        
    }
    
    @Valid
    @NotNull
    public List<Object> getAll() {
        throw new RuntimeException("Gotcha");
    }

}
{code}
This is especially problematic for AOP interceptors: if an AOP interceptor is 
used to support bean validation on annotated methods, in the above scenario the 
AOP interceptor will pass the intercepted method to BVal, which will then 
invoke such method and therefore the AOP interceptor again, which in turn will 
invoke BVal again, resulting in an endless invocation call stack and ultimately 
in a stack overflow error.

I have read the specification and I could not find any reference to the fact 
that validateParameters() should apply cascaded validation to the return value 
of the method, and  invoke the method to achieve this.

This problem only appears if the method looks like a getter for a property. 
Renaming getAll() in the above snippet to something different e.g. doAll() 
removes the problem.

There are therefore two workarounds for this issue:
 * work around 1: don't call validateParameters() if the method has no input 
parameter
 * work around 2: make sure your methods with no-args do not start with "get*" 
so that they are not confused with getters.

 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to