[jboss-dev-forums] [Design the new POJO MicroContainer] - How to reliably determine if BeanMetaData contains dependenc

kabir.khan@jboss.com do-not-reply at jboss.com
Wed Feb 4 12:27:00 EST 2009


I need a way to reliably determine if a BeanMetaData contains dependencies. aop-mc-int tests in trunk for aspects with dependencies are failing due to my way of determining this no longer working there, and this in turn causes aop failures in AS Branch_2_0 with the latest mc jars.

The background is: when reading the aop.xml I create different underlying beans in
https://svn.jboss.org/repos/jbossas/projects/microcontainer/trunk/aop-mc-int/src/main/java/org/jboss/aop/microcontainer/beans/metadata/AspectBeanMetaDataFactory.java
depending on if the bean has dependencies 

  | <aop xmlns="urn:jboss:aop-beans:1.0">
  |    <aspect class="org.jboss.test.microcontainer.beans.TestAspectWithDependency">
  |    	<property name="dependency"><inject bean="Dependency"/></property>
  |    </aspect>
  | </aop>
  | 
or not

  | <aop xmlns="urn:jboss:aop-beans:1.0">
  |    <aspect class="org.jboss.test.microcontainer.beans.TestAspect">
  |    </aspect>
  | </aop>
  | 

This gets parsed by AspectBMDFactory

  |    @Override
  |    public List<BeanMetaData> getBeans()
  |    {
  |       ArrayList<BeanMetaData> result = new ArrayList<BeanMetaData>();
  |       
  |       if (this.name == null)
  |       {
  |          this.name = super.getBean();
  |       }
  |       
  |       //Add the bean factory
  |       if (!initialisedName)
  |       {
  |          aspectName = this.name;
  |          this.name = "Factory$" + name;
  |          initialisedName = true;
  |       }
  |       List<BeanMetaData> beans = super.getBeans();
  |       if (beans.size() != 1)
  |       {
  |          throw new RuntimeException("Wrong number of beans" + beans);
  |       }
  |       BeanMetaData factory = beans.get(0);
  |       BeanMetaDataBuilder factoryBuilder = BeanMetaDataBuilder.createBuilder(factory);
  |       factoryBuilder.setBean(ClassLoaderAwareGenericBeanFactory.class.getName());
  |       result.add(factory);
  |       
  |       //Add the Aspect
  |       BeanMetaDataBuilder aspectBuilder = BeanMetaDataBuilder.createBuilder(aspectName, Aspect.class.getName());
  |       aspectBuilder.addPropertyMetaData("scope", scope);
  |       aspectBuilder.addPropertyMetaData("name", aspectName);
  |       HashMap<String, String> attributes = new HashMap<String, String>();
  |       attributes.put("name", name);
  |       if (factory != null)
  |       {
  |          attributes.put("factory", this.factory);
  |       }
  |       else
  |       {
  |          attributes.put("class", bean);
  |       }
  |       attributes.put("scope", scope);
  |       if (elements != null && elements.size() > 0)
  |       {
  |          aspectBuilder.addPropertyMetaData("element", XmlLoadableRootElementUtil.getRootElementString(elements, getTagName(), attributes));
  |       }
  |          
  |       setAspectManagerProperty(aspectBuilder);
  |       
  |       if (this.factory != null)
  |       {
  |          aspectBuilder.addPropertyMetaData("factory", Boolean.TRUE);
  |       }
  |       result.add(aspectBuilder.getBeanMetaData());
  |       
  |       System.out.println(factory.getRelated());
  |       
  |       if (hasInjectedBeans(factory))
  |       {
  |          configureWithDependencies(factoryBuilder, aspectBuilder);
  |       }
  |       else
  |       {
  |          configureNoDependencies(aspectBuilder);
  |       }
  | 
  |       return result;
  |    }
  | 
The code I had, hasInjectedBeans(), to determine whether there are any dependencies for "factory" worked properly in MC Branch_2_0, but always returns false in trunk. I've added some modifications locally to inspect what it is doing

  |   private boolean hasInjectedBeans(BeanMetaData beanMetaData)
  |   {
  |      ArrayList<ValueMetaData> dependencies = new ArrayList<ValueMetaData>();
  |      System.out.println("======== Getting dependencies");
  |      getDependencies(dependencies, beanMetaData, 0);
  |      
  |      for (ValueMetaData dep : dependencies)
  |      {
  |         if(!((String)dep.getUnderlyingValue()).startsWith("jboss.kernel:service="))
  |         {
  |            return true;
  |         }
  |      }
  |      return false;
  |   }
  |   
  |   private void getDependencies(ArrayList<ValueMetaData> dependencies, MetaDataVisitorNode node, int i)
  |   {
  |      System.out.println(indent(i) + node);
  |      Iterator<? extends MetaDataVisitorNode> children = node.getChildren();
  |      
  |      if (children != null)
  |      {
  |         while (children.hasNext())
  |         {
  |            MetaDataVisitorNode child = children.next();
  |            if (child instanceof AbstractDependencyValueMetaData)
  |            {
  |               System.out.println(indent(i+1) + "DEPENDENCY: " + child);
  |               dependencies.add((AbstractDependencyValueMetaData)child);
  |            }
  |            getDependencies(dependencies, child, i + 1);
  |         }
  |      }
  |   }
  |   
  |   private String indent(int l)
  |   {
  |      String s = "-";
  |      for (int i = 0 ; i < l ; i++)
  |      {
  |         s = s + "-";
  |      }
  |      return s;
  |   }
  | 
The output when parsing

  | <aop xmlns="urn:jboss:aop-beans:1.0">
  |    <aspect class="org.jboss.test.microcontainer.beans.TestAspectWithDependency">
  |    	<property name="dependency"><inject bean="Dependency"/></property>
  |    </aspect>
  | </aop>
  | 
in Branch_2_0

  | ======== Getting dependencies
  | -AbstractBeanMetaData at c59085{name=Factory$org.jboss.test.microcontainer.beans.TestAspectWithDependency bean=org.jboss.aop.microcontainer.bea
  | ns.ClassLoaderAwareGenericBeanFactory properties=[bean, properties] constructor=AbstractConstructorMetaData at 1d0462{parameters=[org.jboss.ker
  | nel.spi.config.KernelConfigurator]} autowireCandidate=true related=[org.jboss.test.microcontainer.beans.TestAspectWithDependency]}
  | --AbstractPropertyMetaData at 908404{name=bean value=StringValueMetaData at 6cf4f9{value=org.jboss.test.microcontainer.beans.TestAspectWithDepende
  | ncy}}
  | ---StringValueMetaData at 6cf4f9{value=org.jboss.test.microcontainer.beans.TestAspectWithDependency}
  | --AbstractPropertyMetaData at cc2f42{name=properties value=AbstractValueMetaData at 470a37{value={dependency=AbstractInjectionValueMetaData at efbbb1
  | {value=Dependency injectionType=BY_CLASS}}}}
  | ---AbstractValueMetaData at 470a37{value={dependency=AbstractInjectionValueMetaData at efbbb1{value=Dependency injectionType=BY_CLASS}}}
  | ----{dependency=AbstractInjectionValueMetaData at efbbb1{value=Dependency injectionType=BY_CLASS}}
  | -----DEPENDENCY: AbstractInjectionValueMetaData at efbbb1{value=Dependency injectionType=BY_CLASS}
  | -----AbstractInjectionValueMetaData at efbbb1{value=Dependency injectionType=BY_CLASS}
  | --AbstractConstructorMetaData at 1d0462{parameters=[org.jboss.kernel.spi.config.KernelConfigurator]}
  | ---AbstractParameterMetaData at b73e5{type=org.jboss.kernel.spi.config.KernelConfigurator value=AbstractDependencyValueMetaData at e5e871{value=jb
  | oss.kernel:service=KernelConfigurator}}
  | ----DEPENDENCY: AbstractDependencyValueMetaData at e5e871{value=jboss.kernel:service=KernelConfigurator}
  | ----AbstractDependencyValueMetaData at e5e871{value=jboss.kernel:service=KernelConfigurator}
  | --AbstractRelatedClassMetaData at ff6313{name=org.jboss.test.microcontainer.beans.TestAspectWithDependency, enabled=null}
  | 
You can see it properly picks out the bean called "Dependency". In trunk it does not work due to a new structure of the bean metadata

  | ======== Getting dependencies
  | -AbstractBeanMetaData at 88f1c5{name=Factory$org.jboss.test.microcontainer.beans.TestAspectWithDependency bean=org.jboss.aop.microcontainer.bea
  | ns.ClassLoaderAwareGenericBeanFactory properties=[properties, bean] constructor=AbstractConstructorMetaData at 3291db{parameters=[org.jboss.ker
  | nel.spi.config.KernelConfigurator]} autowireCandidate=true related=[org.jboss.test.microcontainer.beans.TestAspectWithDependency]}
  | --AbstractPropertyMetaData at 33b5db{name=properties value=AbstractValueMetaData at ad2911{value={dependency=PropertyMap$ValueInfo at 6339b2{}}}}
  | ---AbstractValueMetaData at ad2911{value={dependency=PropertyMap$ValueInfo at 6339b2{}}}
  | ----{dependency=PropertyMap$ValueInfo at 6339b2{}}
  | -----PropertyMap$ValueInfo at 6339b2{}
  | --AbstractPropertyMetaData at 363bce{name=bean value=StringValueMetaData at 61091e{value=org.jboss.test.microcontainer.beans.TestAspectWithDepende
  | ncy}}
  | ---StringValueMetaData at 61091e{value=org.jboss.test.microcontainer.beans.TestAspectWithDependency}
  | --AbstractConstructorMetaData at 3291db{parameters=[org.jboss.kernel.spi.config.KernelConfigurator]}
  | ---AbstractParameterMetaData at 9dbc5c{type=org.jboss.kernel.spi.config.KernelConfigurator value=AbstractDependencyValueMetaData at b967ed{value=j
  | boss.kernel:service=KernelConfigurator}}
  | ----DEPENDENCY: AbstractDependencyValueMetaData at b967ed{value=jboss.kernel:service=KernelConfigurator}
  | ----AbstractDependencyValueMetaData at b967ed{value=jboss.kernel:service=KernelConfigurator}
  | --AbstractRelatedClassMetaData at 562d4b{name=org.jboss.test.microcontainer.beans.TestAspectWithDependency, enabled=null}
  | 

That will teach me not to rely on implementation details... 

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4207075#4207075

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4207075



More information about the jboss-dev-forums mailing list