While using DefaultProviderResolver, we get the following error when there are multiple validator implementations in classpath and one ahead in the classpath is not class loader compatible with the api jar:
I have tracked the error down to beanvalidation-api/src/main/java/javax/validation/Validation.java where it is not handling ServiceConfigurationError correctly. This code was introduced in BVAL-298. There was a discussion about ServiceConfigurationError in as well. The correct thing to do is to ignore the ServiceConfigurationError and try the next available provider. I am attaching a patch to this effect.
The patch fails the unit tests, but after looking at the tests, I believe the tests are at fault. So, change the test when accept the patch.
The underlying service discovery issue manifests differently when an earlier version of bean validator is used which didn't use java.util.ServiceLoader:
See for more details about how the earlier code looked like.
Could you describe your precise setup? Which providers do you have on the classpath?
So what are you saying here. You want to use the Bean Validation API version 1.1, but have say Hibernate Validator 4 (Bean Validation 1.0 compatible) and Hibernate Validator 5 (BV 1.1 compatible) on the classpath at the same time? That does not sound like a good idea to me.
Sorry for the delayed response. I didn't get notification from JIRA for some reason.
In the presence of a module system, it is possible to have more than one provider configured in the system. See the scenario below where we see the problem:
Each jar is a module (say OSGi bundle).
m1.jar depends on BV_1.0.jar
m2.jar depends on BV_1.1.jar
TCL have both BV_1.0.jar and BV_2.0.jar
m2.jar calls BV.getValidator() or the equivalent factory method.
Since m2.jar depends on BV_1.1.jar, it uses BV 1.1 API. BV uses TCL while using ServiceLoader to find a provider. ServiceLoader upon finding META-INF/services of BV_1.0.jar, tries to load it and throws a ServiceConfigurationError since the loaded class does not implement the interface requested by user. ServiceLoader actually allows it to be used to try the next available provider. Check the documentation of java.util.ServiceLoader.iterator(). Instead of trying the next available provider, BV returns immediately. It does not attempt to recover from situations where it can. That's the bug IMO. If you want to call it an RFE, I am fine too as long as you address it.
Can you tell me why you think trying the next provider is actually a bad thing? What would have gone wrong in such a case?