# Bootstrapping

We already seen in the easiest way to create a Validator instance - Validation.buildDefaultValidatorFactory. In this chapter we have a look at the other methods in javax.validation.Validation and how they allow to configure several aspects of Bean Validation at bootstrapping time.

The different bootstrapping options allow, amongst other things, to bootstrap any Bean Validation implementation on the classpath. Generally, an available provider is discovered by the Java Service Provider mechanism. A Bean Validation implementation includes the file `javax.validation.spi.ValidationProvider` in `META-INF/services`. This file contains the fully qualified classname of the ValidationProvider of the implementation. In the case of Hibernate Validator this is org.hibernate.validator.HibernateValidator.

If there are more than one Bean Validation implementation providers in the classpath and Validation.buildDefaultValidatorFactory() is used, there is no guarantee which provider will be chosen. To enforce the provider Validation.byProvider() should be used.

## Configuration and ValidatorFactory

There are three different methods in the Validation class to create a Validator instance. The easiest in shown in .

Validation.buildDefaultValidatorFactory()

    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    Validator validator = factory.getValidator();

You can also use the method Validation.byDefaultProvider() which will allow you to configure several aspects of the created Validator instance:

Validation.byDefaultProvider()

    Configuration<?> config = Validation.byDefaultProvider().configure();
    config.messageInterpolator(new MyMessageInterpolator())
        .traversableResolver( new MyTraversableResolver())
        .constraintValidatorFactory(new MyConstraintValidatorFactory());

    ValidatorFactory factory = config.buildValidatorFactory();
    Validator validator = factory.getValidator();

We will learn more about MessageInterpolator, TraversableResolver and ConstraintValidatorFactory in the following sections.

Last but not least you can ask for a Configuration object of a specific Bean Validation provider. This is useful if you have more than one Bean Validation provider in your classpath. In this situation you can make an explicit choice about which implementation to use. In the case of Hibernate Validator the Validator creation looks like:

Validation.byProvider( HibernateValidator.class )

    HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();
    config.messageInterpolator(new MyMessageInterpolator())
        .traversableResolver( new MyTraversableResolver())
        .constraintValidatorFactory(new MyConstraintValidatorFactory());

    ValidatorFactory factory = config.buildValidatorFactory();
    Validator validator = factory.getValidator();

The generated Validator instance is thread safe and can be cached.

## ValidationProviderResolver

In the case that the Java Service Provider mechanism does not work in your environment or you have a special classloader setup, you are able to provide a custom ValidationProviderResolver. An example in an OSGi environment you could plug your custom provider resolver like seen in .

Providing a custom ValidationProviderResolver

    Configuration<?> config = Validation.byDefaultProvider()
        .providerResolver( new OSGiServiceDiscoverer() )
        .configure();

    ValidatorFactory factory = config.buildValidatorFactory();
    Validator validator = factory.getValidator();

Your OSGiServiceDiscoverer must in this case implement the interface ValidationProviderResolver:

ValidationProviderResolver interface

    public interface ValidationProviderResolver {
        /**
         * Returns a list of ValidationProviders available in the runtime environment.
         *
         * @return list of validation providers.
         */
        List<ValidationProvider<?>> getValidationProviders();
    }

## MessageInterpolator

already discussed the default message interpolation algorithm. If you have special requirements for your message interpolation you can provide a custom interpolator using Configuration.messageInterpolator(). This message interpolator will be shared by all validators generated by the ValidatorFactory created from this Configuration. shows an interpolator (available in Hibernate Validator) which can interpolate the value being validated in the constraint message. To refer to this value in the constraint message you can use:

- ${validatedValue}: this will call String.valueOf on the validated value.

- ${validatedValue:<format>}: provide your own format string which will be passed to `String.format` together with the validated value. Refer to the javadoc of `String.format` for more information about the format options.

Providing a custom MessageInterpolator

    Configuration<?> configuration = Validation.byDefaultProvider().configure();
    ValidatorFactory factory = configuration
        .messageInterpolator(new ValueFormatterMessageInterpolator(configuration.getDefaultMessageInterpolator()))
        .buildValidatorFactory();

    Validator validator = factory.getValidator();

It is recommended that MessageInterpolator implementations delegate final interpolation to the Bean Validation default MessageInterpolator to ensure standard Bean Validation interpolation rules are followed. The default implementation is accessible through Configuration.getDefaultMessageInterpolator().

### ResourceBundleLocator

A common use case is the ability to specify your own resource bundles for message interpolation. The default MessageInterpolator implementation in Hibernate Validator is called ResourceBundleMessageInterpolator and per default loads resource bundles via ResourceBundle.getBundle. However, ResourceBundleMessageInterpolator also allows you to specify a custom implementation of ResourceBundleLocator allowing you to provide your own resource bundles. shows an example. In the example HibernateValidatorConfiguration.getDefaultResourceBundleLocator is used to retrieve the default ResourceBundleLocator which then can be passed to the custom implementation in order implement delegation.

Providing a custom ResourceBundleLocator

    HibernateValidatorConfiguration configure = Validation.byProvider(HibernateValidator.class).configure();

    ResourceBundleLocator defaultResourceBundleLocator = configure.getDefaultResourceBundleLocator();
    ResourceBundleLocator myResourceBundleLocator = new MyCustomResourceBundleLocator(defaultResourceBundleLocator);

    configure.messageInterpolator(new ResourceBundleMessageInterpolator(myResourceBundleLocator));

Hibernate Validator provides the following implementation of ResourceBundleLocator - PlatformResourceBundleLocator (the default) and AggregateResourceBundleLocator. The latter can be used to specify a list of resource bundle names which will get loaded and merged into a single resource bundle. Refer to the JavaDoc documentation for more information.

## TraversableResolver

The usage of the TraversableResolver has so far not been discussed. The idea is that in some cases, the state of a property should not be accessed. The most obvious example for that is a lazy loaded property or association of a Java Persistence provider. Validating this lazy property or association would mean that its state would have to be accessed triggering a load from the database. Bean Validation controls which property can and cannot be accessed via the TraversableResolver interface (see ). In the example HibernateValidatorConfiguration.

TraversableResolver interface

    /**
     * Contract determining if a property can be accessed by the Bean Validation provider
     * This contract is called for each property that is being either validated or cascaded.
     *
     * A traversable resolver implementation must be thread-safe.
     *
     */
    public interface TraversableResolver {
        /**
         * Determine if the Bean Validation provider is allowed to reach the property state
         *
         * @param traversableObject object hosting <code>traversableProperty</code> or null
         *                          if validateValue is called
         * @param traversableProperty the traversable property.
         * @param rootBeanType type of the root object passed to the Validator.
         * @param pathToTraversableObject path from the root object to
         *        <code>traversableObject</code>
         *        (using the path specification defined by Bean Validator).
         * @param elementType either <code>FIELD</code> or <code>METHOD</code>.
         *
         * @return <code>true</code> if the Bean Validation provider is allowed to
         *         reach the property state, <code>false</code> otherwise.
         */
         boolean isReachable(Object traversableObject,
                             Path.Node traversableProperty,
                             Class<?> rootBeanType,
                             Path pathToTraversableObject,
                             ElementType elementType);

        /**
         * Determine if the Bean Validation provider is allowed to cascade validation on
         * the bean instance returned by the property value
         * marked as <code>@Valid</code>.
         * Note that this method is called only if isReachable returns true for the same set of
         * arguments and if the property is marked as <code>@Valid</code>
         *
         * @param traversableObject object hosting <code>traversableProperty</code> or null
         *                          if validateValue is called
         * @param traversableProperty the traversable property.
         * @param rootBeanType type of the root object passed to the Validator.
         * @param pathToTraversableObject path from the root object to
         *        <code>traversableObject</code>
         *        (using the path specification defined by Bean Validator).
         * @param elementType either <code>FIELD</code> or <code>METHOD</code>.
         *
         * @return <code>true</code> if the Bean Validation provider is allowed to
         *         cascade validation, <code>false</code> otherwise.
         */
         boolean isCascadable(Object traversableObject,
                              Path.Node traversableProperty,
                              Class<?> rootBeanType,
                              Path pathToTraversableObject,
                              ElementType elementType);
    }

Hibernate Validator provides two TraversableResolvers out of the box which will be enabled automatically depending on your environment. The first is the DefaultTraversableResolver which will always return true for isReachable() and isTraversable(). The second is the JPATraversableResolver which gets enabled when Hibernate Validator gets used in combination with JPA 2. In case you have to provide your own resolver you can do so again using the Configuration object as seen in .

Providing a custom TraversableResolver

    Configuration<?> configuration = Validation.byDefaultProvider().configure();
    ValidatorFactory factory = configuration
        .traversableResolver(new MyTraversableResolver())
        .buildValidatorFactory();

    Validator validator = factory.getValidator();

## ConstraintValidatorFactory

Last but not least, there is one more configuration option to discuss, the ConstraintValidatorFactory. The default ConstraintValidatorFactory provided by Hibernate Validator requires a public no-arg constructor to instantiate ConstraintValidator instances (see ). Using a custom ConstraintValidatorFactory offers for example the possibility to use dependency injection in constraint implementations. The configuration of the custom factory is once more via the Configuration ().

Providing a custom ConstraintValidatorFactory

    Configuration<?> configuration = Validation.byDefaultProvider().configure();
    ValidatorFactory factory = configuration
        .constraintValidatorFactory(new IOCConstraintValidatorFactory())
        .buildValidatorFactory();

    Validator validator = factory.getValidator();

The interface you have to implement is:

ConstraintValidatorFactory interface

    public interface ConstraintValidatorFactory {
        /**
         * @param key The class of the constraint validator to instantiate.
         *
         * @return A constraint validator instance of the specified class.
         */
         <T extends ConstraintValidator<?,?>> T getInstance(Class<T> key);
    }

Any constraint implementation relying on ConstraintValidatorFactory behaviors specific to an implementation (dependency injection, no no-arg constructor and so on) are not considered portable.

ConstraintValidatorFactory should not cache instances as the state of each instance can be altered in the initialize method.