Dependency on non-existant bean when trying to create
kabirkhan Nov 3, 2009 1:11 PMWhat's wrong with this? Attempting to add the intermediate bean mentioned in http://www.jboss.org/index.html?module=bb&op=viewtopic&t=162791. I found that adding BeanMetaData as a property to a bean seems to cause an unresolved dependency:
public class ThrowawayTestCase extends MicrocontainerTest
{
public ThrowawayTestCase(String name)
{
super(name);
}
public void testIndirectBean() throws Throwable
{
BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder("Bean", MyBean.class.getName());
BeanMetaData bmd = builder.getBeanMetaData();
builder = BeanMetaDataBuilder.createBuilder("BeanInstaller", MyBeanInstaller.class.getName());
// builder.addPropertyMetaData("context", builder.createFromContextInject(FromContext.CONTEXT)); //1
builder.addPropertyMetaData("beanMetaData", builder.createValue(bmd)); //2
KernelControllerContext ctx = deploy(builder.getBeanMetaData());
try
{
System.out.println("----------> " + ctx.getDependencyInfo().getIDependOn(null));
MyBeanInstaller myBeanInstaller = assertBean("BeanInstaller", MyBeanInstaller.class);
// MyBean myBean = assertBean("MyBean", MyBean.class);
// assertNotNull(myBean);
}
finally
{
undeploy(ctx);
}
}
public static class MyBeanInstaller
{
KernelControllerContext context;
BeanMetaData beanMetaData;
boolean started;
public BeanMetaData getBeanMetaData()
{
return beanMetaData;
}
public void setBeanMetaData(BeanMetaData beanMetaData)
{
this.beanMetaData = beanMetaData;
}
public KernelControllerContext getContext()
{
return context;
}
public void setContext(KernelControllerContext context)
{
this.context = context;
}
public boolean isStarted()
{
return started;
}
public void start() throws Exception
{
//Use context.getController() and beanmetadata to install indirect bean
}
}
public static class MyBean
{
}
}
The output dependency info is shown as:
----------> [AbstractDependencyItem@5f49d886{name=BeanInstaller dependsOn=Bean whenRequired=Configured dependentState=Installed resolved=false}]
Looking at the stack trace of AbstractDependencyItem's constructor it looks like the property value gets visited as well?
Thread [main] (Suspended (breakpoint at line 78 in AbstractDependencyItem)) AbstractDependencyItem.<init>(Object, Object, ControllerState, ControllerState) line: 78 AbstractBeanMetaData.initialVisit(MetaDataVisitor) line: 669 PreprocessMetaDataVisitor(AbstractMetaDataVisitor).internalInitialVisit(MetaDataVisitorNode) line: 111 PreprocessMetaDataVisitor(AbstractMetaDataVisitor).initialVisit(MetaDataVisitorNode) line: 74 AbstractValueMetaData.initialVisit(MetaDataVisitor) line: 116 PreprocessMetaDataVisitor(AbstractMetaDataVisitor).internalInitialVisit(MetaDataVisitorNode) line: 111 PreprocessMetaDataVisitor(AbstractMetaDataVisitor).initialVisit(MetaDataVisitorNode) line: 74 AbstractPropertyMetaData(AbstractFeatureMetaData).initialVisit(MetaDataVisitor) line: 101 AbstractPropertyMetaData.initialVisit(MetaDataVisitor) line: 287 PreprocessMetaDataVisitor(AbstractMetaDataVisitor).internalInitialVisit(MetaDataVisitorNode) line: 111 PreprocessMetaDataVisitor(AbstractMetaDataVisitor).initialVisit(MetaDataVisitorNode) line: 74 AbstractBeanMetaData(AbstractFeatureMetaData).initialVisit(MetaDataVisitor) line: 101 AbstractBeanMetaData.initialVisit(MetaDataVisitor) line: 680 PreprocessMetaDataVisitor.run() line: 53 AccessController.doPrivileged(PrivilegedAction<T>) line: not available [native method] AbstractKernelControllerContext.preprocessMetaData() line: 232 AbstractKernelControllerContext.setController(Controller) line: 198 AbstractKernelController(AbstractController).install(ControllerContext, boolean) line: 778 AbstractKernelController(AbstractController).install(ControllerContext) line: 564 AbstractKernelController.install(BeanMetaData, Object) line: 107 AbstractKernelController.install(BeanMetaData) line: 101 MicrocontainerTestDelegate.deploy(BeanMetaData) line: 329 ThrowawayTestCase(MicrocontainerTest).deploy(BeanMetaData) line: 358 ThrowawayTestCase.testIndirectBean() line: 54
I'm not sure this is something we should fix, without a better understanding of how the value metadata is visited. I can work around it by creating an intermediate class
public static class BeanMetaDataWrapper
{
private final BeanMetaData beanMetaData;
public BeanMetaDataWrapper(BeanMetaData beanMetaData)
{
this.beanMetaData = beanMetaData;
}
public BeanMetaData getBeanMetaData()
{
return beanMetaData;
}
}
and to set that instead when creating BeanInstaller
builder.addPropertyMetaData("beanMetaDataWrapper", builder.createValue(wrapper));