[bv-dev] Constructor validation

Gunnar Morling gunnar.morling at googlemail.com
Sun Dec 4 10:50:22 EST 2011


Hi Sebastian,

thanks for your message. You're raising a couple of important points
here. Some answers inline.

--Gunnar

[1] http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-customoptions-methodvalidation


2011/12/3 Sebastian Thomschke <sebastian.thomschke at web.de>:
> Constraints you add to a property are constraints that are used to
> determine an object's state (valid or invalid).
> Constraints you add to parameters are preconditions and must be
> satisfied before the method body is allowed to be executed. So yes, I
> think there is a semantic difference.
> Now the question is in which cases are those preconditions evaluated?
> When you manually invoke the method somewhere in your code or only when
> the method is invoked explicitly via e.g. a DI framework that itself
> utilizes BV.
> As long as this is addressed in the specs I'm fine.
> In OVal for example preconditions are only evaluated automatically when
> your project is setup for programming by contract correctly as
> documented here:
> http://oval.sourceforge.net/userguide.html#programming-by-contract
>
> Other interesting aspects regarding constructor/method validation that
> should be addressed are:
> - do we support parameters on static methods?

Personally I don't think we should. Static members are excluded for
standard bean validation (see section 3.1), and I think we should be
consistent with that for method validation (or remove that restriction
also for standard validation).

> - which visibilities do we support? public, private, package, protected?
> all?

Is there any reason to limit this? If not, I wouldn't restrict the
supported visibility from the Bean Validation side. I think this
mainly depends on how method validation is integrated.

As validation is typically triggered by some container, only "managed"
method invocations can usually be validated, i.e. methods invoked by
other managed beans, but not directly invoked private methods.

If OTOH someone builds an integration of the method validation feature
using AOP/byte code manipulation, I guess also private methods
wouldn't be a problem.

> - inheritance: you pass a java.lang.Method object of class A to
> validateMethodParameters() and an object of class B extending class A
> which overrides this method. Which constraints are checked, the ones of
> the method declared on class A, the ones declared on the method of class
> B or the sum of the methods in A & B?

That's a very good question.

In fact in Hibernate Validator we don't support parameter constraints
in overriding methods at all (so if A#foo() has parameter constraints,
B#foo() must not declare any parameter constraints), as this
represents a strengthening of preconditions in sub-types for clients
of A, which violates the Liskov substitution principle. Some more
reasoning can be found in the HV reference guide in section 8.3.1.1
[1].

I'm preferring this approach, though it is rather conservate. Some
"programming by contract" solutions deal with this by OR-ing the
preconditions in a method's hierarchy (so an invocation would be
valid, if the constraints at A#foo() OR B#foo() are satisfied),
actually applying the "weakest" contract in the hierarchy. How is this
done in OVal? And does anyone know how it is in Apache BVAL?

> - When you add a method return value constraint to a parameterized
> method and you do Validator.validate(object), thoses constraints are not
> evaluated. But when you add a constraint to a getter-style method (which
> also looks and actually is a method return value constraint). They are
> evaluated by Validator.validate(object). What if someone wants to add a
> method return value constraint to a getter-style method, that is not
> evaluated when Validator.validate(object) is executed but after the
> method itself has been invoked? In OVal you have to explicitely add the
> @IsInvariant annotation to getter methods if their constraints should be
> evaluated too when Validator.validate(object) is executed. If so, OVal
> will invoke the getter and test the returned value against the
> constraints specified.

Personally I'd say getters are methods such as any other methods, too.
So if a getter method is invoked one some bean generally qualifying
for method validation (however that is decided by the method
validation integration layer) the method's constraints should be
validated in the same way as any other method constraints. If the bean
is validated using Validator#validate(), the getter method's
constraints should be handled as property constraints as it's the case
today IMO.

>
> Regards,
>
> Seb
>
>
> On 02.12.2011 22:25, Gunnar Morling wrote:
>> Yes, I see. I'm not really sure, what we can do about this except
>> making this very clear in the spec/documentation.
>>
>> After all it's the same thing with "normal" constraints, such as
>> property constraints. Only adding a constraint to a property doesn't
>> cause it to be validated automatically.
>>
>> Or did you have something else in mind?
>>
>>
>> 2011/12/1 Emmanuel Bernard<emmanuel at hibernate.org>:
>>> Yes. That concerns me a bit to be honest especially when more technologies will offer BV integrations. We need to think this through before opening pandora's box even more :)
>>>
>>> On 1 déc. 2011, at 21:48, Sebastian Thomschke<sebastian.thomschke at web.de>  wrote:
>>>
>>>> Ok gotcha.Maybe we should make it clear in the specs that adding
>>>> parameter constraints does not necessarily mean when such a
>>>> constructor/method is invoked from somewhere in unmanaged code that an
>>>> instant validation will happen, but that the time of validation and if a
>>>> validation happens at all depends on the validator implementation.
>>>>
>>>> Regards,
>>>> Seb
>>>>
>>>> On 01.12.2011 21:32, Gunnar Morling wrote:
>>>>> Hi Sebastian,
>>>>>
>>>>> is this really something which we should consider in BV?
>>>>>
>>>>>>  From my point of view we should only provide an API for
>>>>> method/constructor validation (by adding
>>>>> Validator#validateMethodParameters() for instance), but we shouldn't
>>>>> provide a trigger/hook executing this validation. I'd see this as the
>>>>> responsibility of technologies integrating with BV (similar to the
>>>>> existing validate() methods which are invoked by JSF/JPA if
>>>>> applicable).
>>>>>
>>>>> So whether method validation is triggered via a proxy, CDI/Spring AOP
>>>>> interceptor etc. should be transparent for BV IMO.
>>>>>
>>>>> I wasn't sure about whether there is an actual need for constructor
>>>>> validation, but Emmanuel's answer about JAX-RS confirmed that need :)
>>>>>
>>>>> --Gunnar
>>>>>
>>>>>
>>>>> 2011/12/1 Sebastian Thomschke<sebastian.thomschke at web.de>:
>>>>>> Supporting constructor parameter validation as well as validation of
>>>>>> parameters of methods not part of an interface requires some sort of
>>>>>> byte code enhancements and cannot be done via JDK proxying.
>>>>>> So if we find a sufficient solution how to achieve method parameter
>>>>>> validation without JDK proxies I do not see why we should not support
>>>>>> constructor parameter validation too.
>>>>>>
>>>>>> Regards,
>>>>>> Seb
>>>>>>
>>>>>> On 30.11.2011 19:59, Gunnar Morling wrote:
>>>>>>> Hi experts,
>>>>>>>
>>>>>>> Emmanuel asked me to take the lead on the method validation feature,
>>>>>>> so be prepared for related questions, API proposals and requests for
>>>>>>> feedback via the mailing list :)
>>>>>>>
>>>>>>> The first issue I'd like to discuss is the validation of constructor
>>>>>>> arguments. Is this something which we want to support at all? I don't
>>>>>>> think there are that many interception solutions which enable
>>>>>>> constructor interception at all (for instance CDI interceptors don't,
>>>>>>> AFAIK).
>>>>>>>
>>>>>>> So personally I'd be fine with focussing on actual method validation
>>>>>>> in BV 1.1, waiting for user demand for constructor validation and
>>>>>>> adding it possibly in a later release. WDYT?
>>>>>>>
>>>>>>> If we decide to include constructor validation, should we support the
>>>>>>> validation of newly created objects (similar to return value
>>>>>>> validation), e.g. like that:
>>>>>>>
>>>>>>> public class Foo {
>>>>>>>
>>>>>>>     @Valid
>>>>>>>     public Foo() {
>>>>>>>
>>>>>>>     }
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> Here @Valid would trigger a validation of the newly instantiated Foo
>>>>>>> object (whether to use @Valid or another annotation still needs to be
>>>>>>> discussed). Any thoughts?
>>>>>>>
>>>>>>> --Gunnar
>>>>>>> _______________________________________________
>>>>>>> beanvalidation-dev mailing list
>>>>>>> beanvalidation-dev at lists.jboss.org
>>>>>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
>>>>>> _______________________________________________
>>>>>> beanvalidation-dev mailing list
>>>>>> beanvalidation-dev at lists.jboss.org
>>>>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
>>>>> _______________________________________________
>>>>> beanvalidation-dev mailing list
>>>>> beanvalidation-dev at lists.jboss.org
>>>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
>>>> _______________________________________________
>>>> beanvalidation-dev mailing list
>>>> beanvalidation-dev at lists.jboss.org
>>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
>>> _______________________________________________
>>> beanvalidation-dev mailing list
>>> beanvalidation-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
>> _______________________________________________
>> beanvalidation-dev mailing list
>> beanvalidation-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
>
> _______________________________________________
> beanvalidation-dev mailing list
> beanvalidation-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev



More information about the beanvalidation-dev mailing list