In my work on adding management to the service binding manager-related beans, I've
written a MetaMapper subclass and applied it to a property via @MetaMapping on the getter.
My MetaMapper gets invoked when the property is read, but when a
ManagementView.updateComponent call results in a call to the setter, the MetaMapper
isn't used, resulting in an exception.
Walking through this in a debugger, I think the problem is in BeanMetaDataICF:
| public void setValue(BeanInfo beanInfo, ManagedProperty property,
| BeanMetaData attachment, MetaValue value)
| {
| ClassLoader prevLoader = SecurityActions.getContextClassLoader();
| String beanName = attachment.getName();
| // First look to the mapped name
| String name = property.getMappedName();
| if (name == null)
| name = property.getName();
| try
| {
| ClassLoader loader = getClassLoader(attachment);
| // Set the mbean class loader as the TCL
| SecurityActions.setContextClassLoader(loader);
|
| PropertyInfo propertyInfo = property.getField(Fields.PROPERTY_INFO,
PropertyInfo.class);
| if(propertyInfo == null)
| propertyInfo = beanInfo.getProperty(name);
| if(propertyInfo == null)
| throw new IllegalArgumentException("No matching property found:
" + name + "/" + beanName);
|
| if(propertyInfo.isWritable() == false)
| {
| if(log.isTraceEnabled())
| log.trace("Skipping get of non-writable property:
"+propertyInfo);
| return;
| }
| Object plainValue = metaValueFactory.unwrap(value, propertyInfo.getType());
| Object bean = locateBean(beanName);
|
| // Only update if the bean is not null
| if(bean != null)
| propertyInfo.set(bean, plainValue);
|
| BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(attachment);
| builder.addPropertyMetaData(name, plainValue);
|
| }
| catch(Throwable e)
| {
| throw new IllegalStateException("Failed to set property value:
"+name + "/" + beanName, e);
| }
| finally
| {
| SecurityActions.setContextClassLoader(prevLoader);
| }
| }
|
The method has access to the ManagedProperty, and my MetaMapper is attached to the
ManagedProperty as a transient attachment. AFAICT the way the MetaMapper is found when the
getter is called is via that transient attachment. But the above code does not look for
the MetaMapper there; it just delegates to DefaultMetaValueFactory, which uses
MetaMapper.getMetaMapper(). MetaMapper.getMetaMapper() will only find a MetaMapper if it
is
1) Attached to the TypeInfo
2) Specified via an annotation on the class
Here the type is java.util.Set<org.jboss.services.binding.ServiceBindingMetadata>,
so of course #2 doesn't apply and adding an attachment so #1 would work seems
problematic. I suspect that's why the approach of adding the MetaMapper as a transient
attachment to the ManagedProperty is there.
Should BeanMetaDataICF have logic added to look for the MetaMapper in the ManagedProperty?
Or should the MetaMapper have somehow been attached to the TypeInfo so #1 would work? I
doubt the latter.
I think I can find a workaround for this for my SBM work, but it will force me to annotate
a class with @MetaMapping when I don't want to. I'm trying to avoid adding
hard-coded dependencies on jboss-managed and jboss-metatype to the SBM classes.
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4229506#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...