7 Replies Latest reply on Mar 25, 2008 11:24 AM by Ales Justin

    beanfactory injection

    Scott Stark Master

      The org.jboss.test.kernel.deployment.test.BeanContainerUsageTestCase which has this xml deployment:

      <?xml version="1.0" encoding="UTF-8"?>
      
      <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
       xmlns="urn:jboss:bean-deployer">
      
       <beanfactory name="Bean1TypeFactory" class="org.jboss.test.kernel.deployment.support.container.Bean1Type"/>
       <bean name="Bean1TypePool" class="org.jboss.test.kernel.deployment.support.container.BeanPool">
       <property name="factory"><inject name="Bean1TypeFactory"/></property>
       </bean>
       <bean name="BeanContainer1Type" class="org.jboss.test.kernel.deployment.support.container.BeanContainer">
       <property name="pool"><inject name="Bean1TypePool"/></property>
       </bean>
       <beanfactory name="Bean2TypeFactory" class="org.jboss.test.kernel.deployment.support.container.Bean2Type">
       <property name="bean1"><value-factory bean="Bean1TypeFactory" method="createBean" /></property>
       </beanfactory>
       <bean name="Bean2TypePool" class="org.jboss.test.kernel.deployment.support.container.BeanPool">
       <property name="factory"><inject name="Bean2TypeFactory"/></property>
       </bean>
       <bean name="BeanContainer2Type" class="org.jboss.test.kernel.deployment.support.container.BeanContainer">
       <property name="pool"><inject name="Bean2TypePool"/></property>
       </bean>
      
      </deployment>
      


      is failing because of a class dependency on the org.jboss.beans.metadata.spi.factory.BeanFactory type being injected into the bean pool:

      java.lang.IllegalStateException: Incompletely deployed:
      
      *** DEPLOYMENTS MISSING DEPENDENCIES: Name -> Dependency{Required State:Actual State}
      Bean2TypePool -> interface org.jboss.beans.metadata.spi.factory.BeanFactory{Installed:** NOT FOUND **}
      
       at org.jboss.kernel.plugins.deployment.AbstractKernelDeployer.internalValidate(AbstractKernelDeployer.java:290)
       at org.jboss.kernel.plugins.deployment.AbstractKernelDeployer.validate(AbstractKernelDeployer.java:177)
       at org.jboss.test.kernel.junit.MicrocontainerTestDelegate.validate(MicrocontainerTestDelegate.java:262)
       at org.jboss.test.kernel.junit.MicrocontainerTest.afterSetUp(MicrocontainerTest.java:98)
       at org.jboss.test.kernel.junit.MicrocontainerTest.setUp(MicrocontainerTest.java:83)
      


      I assume its because there is a failure to understand that Bean1TypeFactory provides the BeanFactory?


        • 1. Re: beanfactory injection
          Ales Justin Master

           

          "scott.stark@jboss.org" wrote:

          I assume its because there is a failure to understand that Bean1TypeFactory provides the BeanFactory?

          No.
          It's because we don't have validation of xml turned on, and you put 'name' instead of 'bean' in inject element. :-)
          I fixed it in trunk.
          I also had to fix BeanPool in order not to get NPE.

          • 2. Re: beanfactory injection
            Scott Stark Master

            Hmm, ok. Guess I need to look into how to make the error more informative. What was the inject name="..." mapping to?

            • 3. Re: beanfactory injection
              Ales Justin Master

               

              "scott.stark@jboss.org" wrote:
              Guess I need to look into how to make the error more informative.

              Like I said, and I think Adrian also already mentioned, we need to switch on the xml validation, for tests and real usage.
              That would tell you the real problem, 'name' attribute doesn't exist on inject element.

              "scott.stark@jboss.org" wrote:

              What was the inject name="..." mapping to?

              To nothing. It was simply ignored.
              And w/o exact bean the contextual injection kicked in, matching exactly one bean implementing BeanFactory.
              Since there were two, you got a warning (see log), and then a failure that the class (autowire) dependency wasn't resolved.

              • 4. Re: beanfactory injection
                Ales Justin Master

                 

                "alesj" wrote:

                "scott.stark@jboss.org" wrote:

                What was the inject name="..." mapping to?

                To nothing. It was simply ignored.

                I mean the 'name' attribute was ignored.
                Plain 'inject', w/o any attributes, is mapped to AbstractInjectionValueMetaData.
                Which then provides the information for contextual injection.

                • 5. Re: beanfactory injection
                  Adrian Brock Master

                   

                  "alesj" wrote:
                  "scott.stark@jboss.org" wrote:
                  Guess I need to look into how to make the error more informative.

                  Like I said, and I think Adrian also already mentioned, we need to switch on the xml validation, for tests and real usage.
                  That would tell you the real problem, 'name' attribute doesn't exist on inject element.


                  That's a different issue.

                  Turning on xml validation isn't going to help if you construct the BeanMetaData
                  programmatically.

                  We should add something to the "toHumanReadableString()" for the "anonymous inject"
                  to ask whether they intended that it or just forgot to give a bean name. :-)

                  Bean2TypePool -> injection by interface org.jboss.beans.metadata.spi.factory.BeanFactory (or did you forget to supply a bean name for the injection?) {Installed:** NOT FOUND **}
                  


                  Otherwise we're going to get lots of FAQs :-)

                  • 6. Re: beanfactory injection
                    Ales Justin Master

                     

                    "adrian@jboss.org" wrote:

                    We should add something to the "toHumanReadableString()" for the "anonymous inject" to ask whether they intended that it or just forgot to give a bean name. :-)

                    Bean2TypePool -> injection by interface org.jboss.beans.metadata.spi.factory.BeanFactory (or did you forget to supply a bean name for the injection?) {Installed:** NOT FOUND **}
                    


                    Otherwise we're going to get lots of FAQs :-)

                    I'll update the toString/toHumanString for class dependency items.

                    • 7. Re: beanfactory injection
                      Ales Justin Master

                       

                      "alesj" wrote:
                      "adrian@jboss.org" wrote:

                      We should add something to the "toHumanReadableString()" for the "anonymous inject" to ask whether they intended that it or just forgot to give a bean name. :-)

                      Bean2TypePool -> injection by interface org.jboss.beans.metadata.spi.factory.BeanFactory (or did you forget to supply a bean name for the injection?) {Installed:** NOT FOUND **}
                      


                      Otherwise we're going to get lots of FAQs :-)

                      I'll update the toString/toHumanString for class dependency items.

                      This will require update to DeployersImpl:
                       dependency = iDependOn.toString();
                       ControllerContext other = controller.getContext(iDependOn, null);
                       if (other == null)
                       actualStateString = "** NOT FOUND **";
                      

                      I guess this is what we want:
                      actualStateString = "** NOT FOUND " + item.toHumanReadableString() + " **";
                      


                      On a different note, looking at
                       Object iDependOn = item.getIDependOn();
                       if (iDependOn == null)
                       {
                       dependency = "<UNKNOWN>";
                       actualStateString = "** UNRESOLVED " + item.toHumanReadableString() + " **";
                       }
                      

                      and a default impl of toHumanReadableString
                       public String toHumanReadableString()
                       {
                       StringBuilder builder = new StringBuilder();
                       builder.append("Depends on '").append(getIDependOn());
                       return builder.toString();
                       }
                      

                      it seams meaningless, since getIDependOn will return null. :-)
                      OK, but that's impl detail. ;-)