Results 1 to 8 of 8

Thread: Inner bean definitions overwritting each other

  1. #1
    Join Date
    Feb 2007
    Location
    Ann Arbor, Michigan
    Posts
    48

    Default Inner bean definitions overwritting each other

    First, I apologize that I can't give more information on this error that I'm seeing, it's occurring pretty deep in the Spring code and I'm not familiar enough with the Spring code to trace as well as I'd like.

    Here's my basic setup:
    I'm using the Spring 2 (2.0.6) custom XML schema functionality. I have a top level object, lets say FooGroup that has some number of Foo children. Foo object contains a collection of Profiles object.

    FooGroup has a setFoo(List<Foo) method and is created by a simple bean definition parser (extends AbstractSimpleBeanDefinitionParser). Foo objects are built by a bean factory populated another simple bean definition parser. I use a factory because it builds a map from the list of Profiles.

    So, the problematic behavior I'm seeing is as follows. All the Profiles are created properly and added to the Foo object just fine. The rest of the Foo object is created fine as well. However, when Spring goes to create the FooGroup, specifically when it tries to set the collection of Foo object it encounters a problem. It resolves the property that should point the List<Foo> instead to the List<Profile>.

    Tracing through the code I the problem occurs in the AbstractBeanFactoryClass.getObjectForBeanInstance method, specifically at line 1208 when it attempts to fetch a pre-instantiated object from cache. Prior to this step Spring had created the List<Profile> and called it "inner bean" and list<Foo>, called "inner bean#1". However when inspect the cache while Spring is attempting to resolve the List<Foo> property for the FooGroup I see that the List<Profile> property is now registered both under "inner bean" and "inner bean#1". I haven't been able to track down when this overwrite occurs but Spring then errors out with a message that it can't convert Profiles in Foos via a registered property editor (which is true, it wouldn't be able to).

    Can anyone offer some help on this? I'm afraid I don't even understand the problem enough to create a test case to demonstrate it, but I'd be more than happy to test out people's suggestions. If a developer wants to try it out I can point you to the code but it's a multi-module project so it's non-trivial to download and test with.

    Any help would be greatly appreciated.
    Chad

  2. #2
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    Can you post the relevant section of your application context file? Also the stacktrace itself might be helpful.

    And if you post the snippets, please use [ code] [ /code] tags around them to improve their readability.

    Regards,
    Andreas

  3. #3
    Join Date
    Feb 2007
    Location
    Ann Arbor, Michigan
    Posts
    48

    Default

    Hey Andreas

    Not sure what you mean by app context file. Are you talking about the custom xml schema loaded into the context?

    Stack trace below:
    RelyingPartyGroup = FooGroup in generic description above
    relyingParties property = List<Foo>
    RelyingPartyConfiguration = Foo
    ShibbolethSSOProfileHandler = member of List<Profile>

    Code:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'edu.internet2.middleware.shibboleth.common.config.relyingparty.RelyingPartyGroup': Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
    PropertyAccessException 1: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.util.ArrayList] to required type [java.util.List] for property 'relyingParties'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml1.ShibbolethSSOConfiguration] to required type [edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration] for property 'relyingParties[0]': no matching editors or conversion strategy found
    Caused by: 
    org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessException details (1) are:
    PropertyAccessException 1:
    org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.util.ArrayList] to required type [java.util.List] for property 'relyingParties'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml1.ShibbolethSSOConfiguration] to required type [edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration] for property 'relyingParties[0]': no matching editors or conversion strategy found
    Caused by: 
    java.lang.IllegalArgumentException: Cannot convert value of type [edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml1.ShibbolethSSOConfiguration] to required type [edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration] for property 'relyingParties[0]': no matching editors or conversion strategy found
    	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:231)
    	at org.springframework.beans.TypeConverterDelegate.convertToTypedCollection(TypeConverterDelegate.java:401)
    	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:204)
    	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
    	at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:815)
    	at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:645)
    	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:78)
    	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:59)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1126)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:861)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:421)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
    	at edu.internet2.middleware.shibboleth.common.config.BaseService.loadContext(BaseService.java:186)
    	at edu.internet2.middleware.shibboleth.common.config.BaseReloadableService.initialize(BaseReloadableService.java:136)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:585)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1240)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1205)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1171)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:425)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:229)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
    	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:261)
    	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:109)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1099)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:861)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:421)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
    	at edu.internet2.middleware.shibboleth.common.config.BaseService.loadContext(BaseService.java:186)
    	at edu.internet2.middleware.shibboleth.common.config.BaseReloadableService.initialize(BaseReloadableService.java:136)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:585)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1240)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1205)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1171)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:425)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
    	at edu.internet2.middleware.shibboleth.idp.BaseIdPTestCase.createSpringContext(BaseIdPTestCase.java:105)
    	at edu.internet2.middleware.shibboleth.idp.BaseIdPTestCase.createSpringContext(BaseIdPTestCase.java:90)
    	at edu.internet2.middleware.shibboleth.idp.system.conf1.BaseConf1TestCase.setUp(BaseConf1TestCase.java:21)
    	... snip JUnit classes so post will fit
    Chad

  4. #4
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    Quote Originally Posted by daleth View Post
    Hey Andreas

    Not sure what you mean by app context file. Are you talking about the custom xml schema loaded into the context?
    I meant the xml file containing your bean definitions. That would be useful for a diagnose. If it is too large, just post the relevant bean definitions for this case.

    Regards,
    Andreas

  5. #5
    Join Date
    Feb 2007
    Location
    Ann Arbor, Michigan
    Posts
    48

    Default

    Sure. Here ya go.

    Code:
    <RelyingPartyGroup xmlns="urn:mace:shibboleth:2.0:relying-party"
                       xmlns:saml="urn:mace:shibboleth:2.0:relying-party:saml"
                       xmlns:metadata="urn:mace:shibboleth:2.0:metadata"
                       xmlns:security="urn:mace:shibboleth:2.0:security"
                       xmlns:samlsec="urn:mace:shibboleth:2.0:security:saml"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                                           
        <!-- ========================================== -->
        <!--      Relying Party Configurations          -->
        <!-- ========================================== -->
        <!-- 
        <AnonymousRelyingParty provider="http://example.org/IdP" />
        
        <DefaultRelyingParty provider="http://example.org/IdP" />
        -->
            
        <RelyingParty id="urn:example.org:myFederation"
                      provider="urn:example.org:myFederation:idp1">
            <ProfileConfiguration xsi:type="saml:ShibbolethSSOProfile" />
            <!-- 
            <ProfileConfiguration xsi:type="saml:SAML1AttributeQueryProfile" />
            <ProfileConfiguration xsi:type="saml:SAML2SSOProfile" />
            <ProfileConfiguration xsi:type="saml:SAML2AttributeQueryProfile" />
            -->
        </RelyingParty>
        
        <!-- Snip out other stuff -->
    
    </RelyingPartyGroup>
    I tried to do some more tracing through the Spring code and there is definitely something funny going on. In the BeanDefinitionValueResolver.resolveInnerBean method I can see the master bean definition is RelyingPartyConfigurationFactoryBean and then at line 215 is returns the ShibbolethSSOConfiguration object which is not what RelyingPartyConfigurationFactoryBean

    Thanks for helping me with this.
    Chad

  6. #6
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    I'm not sure whether I can provide an explanation here. But maybe you could try setting up a little testcase mirroring your case.

    A type X containing a type Y containing a list of Z. If that test also fails, it might be simpler to check out things.

  7. #7
    Join Date
    Feb 2007
    Location
    Ann Arbor, Michigan
    Posts
    48

    Default

    Okay, I'm able to replicate the problem now with a simple test. I reviewed the documentation and code, regarding custom schemas, bean definition parsers and bean factories to make sure I wasn't doing something silly and as best as I can tell I'm not. I think this may be a bug.

    Andreas, should I submit a bug report with the attached code?
    Chad

  8. #8
    Join Date
    Feb 2007
    Location
    Ann Arbor, Michigan
    Posts
    48

    Default

    I filed a bug report (SPR-3842) and attached the example code demonstrating the problem.
    Chad

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •