Hi Rick,
The code that does the lookup is here in the jetty integration code:
(GeronimoWebAppContext near line 104)
try {
javax.naming.Context ctx = integrationContext.getComponentContext();
Object validatorFactory = ctx.lookup("comp/ValidatorFactory");
setAttribute("javax.faces.validator.beanValidator.ValidatorFactory",
validatorFactory);
} catch (NamingException e) {
// ignore. We just don't set the property if it's not available.
}
I suspect it used to pass because we were only using default validatory
factories so we could always create one. Either that, or we used to throw a
NamingException when we failed (the code you quote catches a naming
exception....).
I wonder if a better solution would be to also catch and ignore a
ValidationException here?
thanks
david jencks
On Oct 21, 2010, at 7:55 AM, Rick McGuire wrote:
> I played around with different solutions and finally came up with something
> that fixes the problem. Unfortunately, I'm not sure what I did is legitimate
> or not. The root problem here is the naming reference implementations were
> throwing ValidationExceptions for any failures with creating a
> ValidatorFactory. This probably was the behavior that should be implemented,
> but unfortunately, the getFederatedBindings() processing was triggering the
> resolution of these objects and the resulting exceptions were causing deploy
> failures. The test cases in question were testing the very conditions that
> triggered the exceptions. The exception was raised, but at deploy time,
> resulting in a test case failure.
>
> I managed to fix this by having the reference objects we bind into jndi catch
> the exceptions and just return null. Everything is passing in the TCK now,
> but I'm not sure returning null is the correct thing to do here.
>
> I'm not really sure how we every were passing 100% in the container with the
> original code. I would have thought that if the same sequence of calls were
> getting made to resolve the provider, then some of the same failures would
> have been seen. I'm going to hold off on committing my changes until I get
> some feedback on this.
>
> Rick
>
> On 10/21/2010 7:48 AM, Rick McGuire wrote:
>> We're down to 13 bean validation failures in the tck now, but these failures
>> are a little puzzling. The tests in error are all giving deploy failures,
>> with the root cause being an exception triggered by getFederatedBindings():
>>
>> java.lang.RuntimeException: javax.naming.NamingException: Validator [Root
>> exception is javax.validation.ValidationException: Unable to find suitable
>> provider: class org.hibernate.jsr303.tck.common.TCKValidationProvider]
>> at
>> org.apache.xbean.naming.context.ContextUtil$ReadOnlyBinding.getObject(ContextUtil.java:201)
>> at
>> org.apache.xbean.naming.context.ContextFederation.getFederatedBindings(ContextFederation.java:118)
>> at
>> org.apache.xbean.naming.context.AbstractFederatedContext.getBindings(AbstractFederatedContext.java:99)
>> at
>> org.apache.xbean.naming.context.AbstractFederatedContext.getBinding(AbstractFederatedContext.java:86)
>> at
>> org.apache.xbean.naming.context.AbstractContext.lookup(AbstractContext.java:133)
>> at
>> org.apache.xbean.naming.context.AbstractContext.lookup(AbstractContext.java:605)
>> at
>> org.apache.geronimo.jetty8.handler.GeronimoWebAppContext.<init>(GeronimoWebAppContext.java:104)
>> at
>> org.apache.geronimo.jetty8.WebAppContextWrapper.<init>(WebAppContextWrapper.java:211)
>> at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
>> Method)
>> at
>> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
>> at
>> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
>> at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
>> at
>> org.apache.xbean.recipe.ReflectionUtil$ConstructorFactory.create(ReflectionUtil.java:952)
>> at
>> org.apache.xbean.recipe.ObjectRecipe.internalCreate(ObjectRecipe.java:276)
>> at
>> org.apache.xbean.recipe.AbstractRecipe.create(AbstractRecipe.java:96)
>> at
>> org.apache.xbean.recipe.AbstractRecipe.create(AbstractRecipe.java:61)
>> at
>> org.apache.geronimo.gbean.runtime.GBeanInstance.createInstance(GBeanInstance.java:933)
>> at
>> org.apache.geronimo.gbean.runtime.GBeanInstanceState.attemptFullStart(GBeanInstanceState.java:271)
>> at
>> org.apache.geronimo.gbean.runtime.GBeanInstanceState.start(GBeanInstanceState.java:105)
>>
>>
>> The root cause of this failure is an exception in
>> DefaultValidatorReference.getContent():
>>
>> @Override
>> public Object getContent()throws NamingException {
>> ValidatorFactory factory =null;
>> try {
>> factory = (ValidatorFactory)new
>> InitialContext().lookup("java:comp/ValidatorFactory");
>> }catch(NamingException e) {
>> factory =Validation.buildDefaultValidatorFactory();
>> }
>> return factory.getValidator();
>> }
>>
>> The root cause of this failure is the NamingException on the .lookup() call.
>> Since this occurs during the building of the federated context, I suspect
>> the initial context is not initialized correctly at this phase. There's a
>> bit of a chicken-and-egg problem here. The buildDefaultValidatorFactory()
>> call is failing because the incorrect thread context classloader is getting
>> used to resolve the provider.
>>
>> The puzzling piece to me is why this process is making the getContent()
>> calls in the first place. Since this binding will create a new instance
>> each time it is requested, either A) an instance is getting created
>> needlessly and thrown away or B) this instance is ending up bound to the
>> JNDI context as a one-off, which would be an incorrect result.
>>
>> I think I can fix this by making the DefaultValidatorReference look up the
>> ValidatorFactoryGBean to obtain the factory used to create the
>> ValidatorInstance rather than doing a jndi lookup, but I want to verify that
>> the lookup occurring at this point is the correct behavior and there's not a
>> better solution available.
>>
>> Rick
>