On 10/21/2010 12:34 PM, David Jencks wrote:
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....).
Ah, I hadn't checked to see what was triggering the call. Yes, that could be a simpler solution to this problem. I'll give that a try.

Rick

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


Reply via email to