-
1. Re: Case sensitivity in injecting a bean's property
alesj Jan 22, 2007 2:32 PM (in response to brian.stansberry)We added direct MBeanServer lookup via attribute for MBeans.
Look-up behaves differently for ServiceControllerContext then for KernelControllerContext.
Look at: http://www.jboss.org/index.html?module=bb&op=viewtopic&t=98875 -
2. Re: Case sensitivity in injecting a bean's property
starksm64 Jan 22, 2007 2:35 PM (in response to brian.stansberry)I noted the issue between bean and mbean property case a while ago:
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=92469
so I'm surprised this is a regression. I don't know why it would have worked because even though the correct case ala java beans for a setPort/getPort is port (based on java.beans.Introspector behavior/javadoc), jmx 1.2, page 40 states:
Case Sensitivity
All attribute and operation names derived from these design patterns are casesensitive.
For example, this means that the methods getstate and setState
define two attributes, one called state that is read-only, and one called State that
is write-only.
While case sensitivity applies directly to component names of standard MBeans, it is
also applicable to all component names of all types of MBeans, standard or dynamic.
In general, all names of classes, attributes, operations, methods, and internal
elements defined in the JMX specification are case sensitive, whether they appear as
data or as functional code when they are manipulated by management operations.
so there are conflicting naming conventions. All I can see that we do is to allow a property matching strictness setting that can be specified when referencing a bean property that would relax the case sensitivity issue. -
3. Re: Case sensitivity in injecting a bean's property
starksm64 Jan 22, 2007 2:38 PM (in response to brian.stansberry)"alesj" wrote:
We added direct MBeanServer lookup via attribute for MBeans.
Look-up behaves differently for ServiceControllerContext then for KernelControllerContext.
Look at: http://www.jboss.org/index.html?module=bb&op=viewtopic&t=98875
Injection of mbean properties had been working before this change though. How was the mbean property name being resolved previously? -
4. Re: Case sensitivity in injecting a bean's property
alesj Jan 22, 2007 3:09 PM (in response to brian.stansberry)"scott.stark@jboss.org" wrote:
How was the mbean property name being resolved previously?
Simple POJO property look-up - via Configurator.
Looks like it worked since there was already a pojo target underlying in ControllerContext. -
5. Re: Case sensitivity in injecting a bean's property
alesj Jan 22, 2007 3:17 PM (in response to brian.stansberry)Before:
Object result = context.getTarget(); if (result != null && property != null) { KernelConfigurator configurator = controller.getKernel().getConfigurator(); BeanInfo beanInfo = configurator.getBeanInfo(result.getClass()); TargettedJoinpoint joinpoint = configurator.getPropertyGetterJoinPoint(beanInfo, property); joinpoint.setTarget(result); result = joinpoint.dispatch(); }
-
6. Re: Case sensitivity in injecting a bean's property
starksm64 Jan 22, 2007 3:31 PM (in response to brian.stansberry)Then we need to look at how the kernel behaves with beans like:
public class BeanWithStates { public String getstate() { return "state"; } public void setstate(String s) { } public int getState() { return 0; } public void setState(int s) { } }
The java.beans.Introspector does not pickup different properties state and State for this:package javabean; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import org.junit.Test; public class TestIntrospector { @Test public void testBeanPropertyCase() throws Exception { BeanInfo beanWithStatesInfo = Introspector.getBeanInfo(BeanWithStates.class); PropertyDescriptor[] props = beanWithStatesInfo.getPropertyDescriptors(); System.out.println("BeanWithStates properties:"); for(PropertyDescriptor p : props) { System.out.println(p.getName()+", read: "+p.getReadMethod()+", write: "+p.getWriteMethod()); } } } BeanWithStates properties: class, read: public final native java.lang.Class java.lang.Object.getClass(), write: null state, read: public java.lang.String javabean.BeanWithStates.getstate(), write: public void javabean.BeanWithStates.setstate(java.lang.String)
Instead, it only finds state, but does use the setter/getter that is consistent with the mbean naming conventions. I guess one would have to supply a class level java.beans.BeanInfo to have access to both state and State as properties. -
7. Re: Case sensitivity in injecting a bean's property
adrian.brock Jan 23, 2007 5:12 AM (in response to brian.stansberry)Ok, so first of all, we need a test for this in system-jmx.
The only test for cross injection just uses the object, it does not test
accessing a "property" of an MBean.
org.jboss.test.system.controller.integration.test.ConfigureMCFromJMXTestCase-mc.xml<deployment xmlns="urn:jboss:bean-deployer:2.0"> <bean name="Test" class="org.jboss.test.system.controller.integration.support.SimpleBean"> <property name="simple"><inject bean="jboss.test:type=test"/></property> </bean> </deployment>
Previously, this just treated the MBean like a javabean
(i.e. the property name was port)
looking directly at the MBean object.
But now it has been changed to go through the JMX api
(so it needs to use the JMX attribute name Port).
Alternatively, we could do as Scott says and try both in ServiceControllerContextpublic Object get(String name) throws Throwable { try { return getMBeanServer().getAttribute(objectName, name); } catch (AttributeNotFoundException orignal) { try { name = switchToUpperOrLowerCase(name); return getMBeanServer().getAttribute(objectName, name); } catch (AttributeNotFoundException e) { throw original; } } }
-
8. Re: Case sensitivity in injecting a bean's property
starksm64 Jan 23, 2007 3:34 PM (in response to brian.stansberry)A task to create the interaction tests
http://jira.jboss.com/jira/browse/JBAS-4009 -
9. Re: Case sensitivity in injecting a bean's property
alesj Dec 6, 2007 5:02 PM (in response to brian.stansberry)I already added this check while working on ProfileService:
protected static String getAttributeName(String name) { if (name == null || name.length() == 0) throw new IllegalArgumentException("Illegal name: " + name); char firstCharacter = name.charAt(0); if (Character.isLowerCase(firstCharacter)) { String attributeName = String.valueOf(Character.toUpperCase(firstCharacter)); if (name.length() > 1) attributeName += name.substring(1); return attributeName; } return name; } public Object get(String name) throws Throwable { return getMBeanServer().getAttribute(objectName, getAttributeName(name)); } public void set(String name, Object value) throws Throwable { Attribute attribute = new Attribute(getAttributeName(name), value); getMBeanServer().setAttribute(objectName, attribute); }
Since we explicitly go over MBeanServer, when accessing MBean's property in MC --> ServiceControllerContext, I see no need to do a switch check.
The test - ConfigureMCFromJMXWithPropertyUnitTestCase - was added to the system-jmx tests.
It checks access to the MBean's attribute both ways - uppercase and lower case first letter.