You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@bval.apache.org by "Matt Benson (JIRA)" <ji...@apache.org> on 2018/10/17 18:12:00 UTC

[jira] [Resolved] (BVAL-158) ExecutableValidator invokes method if it looks like a getter

     [ https://issues.apache.org/jira/browse/BVAL-158?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Matt Benson resolved BVAL-158.
------------------------------
       Resolution: Fixed
    Fix Version/s: 2.0.0

> 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
>            Priority: Major
>             Fix For: 2.0.0
>
>
> 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)