Announcement Announcement Module
Collapse
No announcement yet.
Inner bean definitions overwritting each other Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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.

  • #2
    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

    Comment


    • #3
      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

      Comment


      • #4
        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

        Comment


        • #5
          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.

          Comment


          • #6
            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.

            Comment


            • #7
              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?

              Comment


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

                Comment

                Working...
                X