[bv-dev] Do we need ConstraintValidatorFactory#releaseInstance()?

Emmanuel Bernard emmanuel at hibernate.org
Tue Dec 4 14:19:11 EST 2012


Thanks you for the sum up.

This email is not a rebuttal, more a set of remarks on the subject.

If we manage to remove `releaseInstance()` then we should also remove
`ValidatorFactory.close()`. AFAIR, the only reason for `close()` to
exist is to allow proper implementations of releaseInstance.

The ConstraintValidatorFactory contract is a public contract that can be
implemented by anyone. This is also the way for DI framework to provide
injectable `ConstraintValidator` implementations.

In my mind and in retrospect, `ConstraintValidatorFactory#getInstance()`
should have been named `createInstance()`. Remember, caching is not
allowed in a `CosntraintValidatorFactory` implementation. So you
argument that what creates an object should destroy it applies here:
what requests an object creation should request its destruction and
that's exactly why we have added this method.

>From what you guys say, all implementors of object lifecycle management
libs (let's say DI frameworks) have a @PreDestroy logic that is called
when the CVF bean would be destroyed by its creator. It seems though
that the @PreDestroy method would have to process all objects
returned by `getInstance()`. So `getInstance` would need to keep track
of them in a concurrent structure of some sort.
Is that significantly better than having a `releaseInstance` contract?

Pure JSR-330 implementations have no @PreDestroy concept. Nor does Guice
AFAIK.

Today a Bean Validation implementation can cache ConstraintValidator and
discard them upon memory pressure or if they are never used. If the
@PreDestroy pattern is used, then this optimization is useless as the
object would not be garbage collected until after the CVF is explicitly
destroyed.

It is possible to pass a ConstraintValidatorFactory instance for a
specific validator instance

    Validator validator = validatorFactory
        .usingContext()
            .constraintValidatorFactory(someCVFInstance)
        .getValidator();

In this case and according to the current draft of BV 1.1, the Bean
Validation provider will likely call `getInstance` and `releaseInstance`
for each validate* calls on the `Validator`. It could technically keep
the custom CVF instance around to check if it is reused in a subsequent 
`Validator` creation.

Because of:

- the custom CVF instance per Validator
- the ability to offload cached ConstraintValidator instances
- the ability to implement a dump BV provider that caches nothing

I added what turned out to be a mysterious provision in the spec

> `releaseInstance()` is "typically" invoked when the ValidatorFactory is
> closed

So from what I understand, the choice is between:

- explicit releaseInstance and VF.close() with the benefit of more
  optimizations wrt memory usage - at least not involving custom weak
  reference like implementations
- rely on the @PreDestroy approach - thus limiting CVF implementations with such
  feature - bringing simplicity to the BV provider implementations and
  removing VF.close()

Thoughts?

Emmanuel

On Mon 2012-12-03 12:44, Gunnar Morling wrote:
> Hi all,
> 
> The latest RI version [1] also implements the spec changes regarding the
> integration of BV and CDI.
> 
> During implementation Hardy, Emmanuel and I got into a discussion regarding
> the lifecycle of CDI-managed objects [2] which I'd like to continue.
> 
> The question is whose responsibility is it to release involved objects such
> as message interpolator, traversable resolver or constraint validators.
> Generally we think objects should be released by that party/code that
> created them.
> 
> This means:
> 
> 1) objects created by the user and passed via bootstrap API: to be released
> by user
> 2) objects created by BV implementation (e.g. internal caches): to be
> released by BV implementation
> 3) objects passed by CDI integration layer (e.g. CDI-enabled message
> interpolator etc. based on BootstrapConfiguration): to be released by
> integration layer
> 
> I think 1) is not in our focus, let the user deal with it. For 2) we have
> ValidatorFactory#close(). Interesting is 3). A CDI portable extension could
> make sure that its created managed beans are properly released using CDI's
> pre-destroy hook [3].
> 
> But that way a CDI-enabled ConstraintValidatorFactory could also easily
> release all the constraint validators it created:
> 
> CdiConstraintValidatorFactory implements ConstraintValidatorFactory {
> 
>   public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
>     //create validators. keep track of them.
>   }
> 
>   @PreDestroy
>   public cleanUpValidators() {
>     //release created validators
>   }
> }
> 
> That is, we'd again adhere to the principle that whoever creates objects
> has to release them. When following this approach, we actually wouldn't
> need ConstraintValidatorFactory#releaseInstance() anymore. I think this
> would be a good thing as it IMO simplifies the contract between the BV
> provider and code integrating with it (such as a CDI portable extension)
> and clarifies responsibilities.
> 
> In the spec we would describe that a CDI-enabled CVF has to release its
> validators when it itself is going to be destructed and for
> ValidatorFactory#close(), that a BV provider has to release its internal
> state but no objects passed to it.
> 
> One thing not possible with that approach is to release CV instances before
> the application is shut down. The spec currently says that
> releaseInstance() is "typically" invoked when the ValidatorFactory is
> closed, but AFAICS it leaves room for releasing constraint validators also
> in between. OTOH I wouldn't know when/how a BV provider would decide to do
> that.
> 
> Any thoughts?
> 
> --Gunnar
> 
> [1] http://in.relation.to/Bloggers/HibernateValidator500Alpha2And431Final
> [2] https://hibernate.onjira.com/browse/BVAL-338
> [3] http://docs.oracle.com/javaee/6/tutorial/doc/gmgkd.html

> _______________________________________________
> 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