As with some other JSRs, javax.validation suffers from classloader problems when used in OSGi. At very least, one must manipulate the thread context classloader. I have never succeeded in making the SPI work; all the examples I have seem end up using a customized provider that references HibernateValidator.
Manipulation of the TCCL should not be needed, what you have to do though is to register a custom ValidationProviderResolver which returns the HibernateValidator provider. This is due to a shortcoming of the bootstrapping implementation in the Bean Validation API JAR. We can improve on this in BV.next, there is BVAL-486 for tracking it. In the meantime you can check out how it's done in our OSGi integration tests. Note that there also is HibernateValidatorConfiguration#externalClassLoader(). We'll use that to load any user-provided classes by name, e.g. if you specify constraint mappings in XML. So you should pass in your bundle's classloader via this method.
Hibernate goes and calls the API for javax.el _at the time the application calls validate. So, the application has to come up with a classloader that 'sees' com.sun.el (or whatever) when it calls validate
This is due to EL-based message interpolation, which is a feature defined by Bean Validation. The HV bundle therefore has an optional dependency to EL. So by default there must be an EL bundle in your container, but you can avoid the need for that by configuring org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator as the message interpolator. Then you don't need an EL implementation, but naturally, EL-based interpolation won't work. Note that this affects the default messages of @DecimalMin and @DecimalMax, so you'd have to provide custom messages if you are working with these. |