You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Jan Luehe <Ja...@Sun.COM> on 2005/06/29 02:21:01 UTC
commons-modeler and case sensitivity of property names
Is there a way to have commons-modeler honor the case sensitivity of
Model MBean attribute (property) names?
According to the JMX spec:
All attribute and operation names derived from these design patterns
are case-sensitive. 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 my class that is instrumented as a Model MBean, I have getAbc() and
setAbc() methods, but when I declare "Abc" (instead of "abc") as the
attribute name in the associated mbeans-descriptor.xml, I get a
javax.management.AttributeNotFoundException
("Cannot find attribute abc").
Thanks,
Jan
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org
Re: [digester] Re: Classloading regression between
commons-digester-1.0 and later versions
Posted by Jan Luehe <Ja...@Sun.COM>.
Hi Robert,
robert burrell donkin wrote On 10/01/05 11:11,:
> hi jan
>
> please remember to add the subject prefix for the component.
will remember from now on! :)
> On Thu, 2005-09-29 at 13:57 -0700, Jan Luehe wrote:
>
>>This may be an old topic, but it seems a classloading regression was
>>introduced between commons-digester-1.0 and later versions (including
>>the most recent).
>
>
> this is indeed a very old topic :)
>
> <snip>
>
>>Can someone explain to me the motivation for setting the
>>"useContextClassLoader" property to FALSE by default?
>
>
> i can offer you nothing more than the logs: it is set to FALSE by
> default for no very good reason but most likely since it was felt
> (rightly or wrongly) to preserve backwards compatibility.
>
>
>>We can easily restore the commons-digester-1.0 behaviour in our own
>>code by setting "useContextClassLoader" to TRUE on the Digester
>>instances we acquire. However, this is not possible on "foreign" code
>>that we bundle.
>>
>>It would be useful if Digester.getClassLoader() would also consider a
>>system property (in addition to its own "useContextClassLoader"
>>property) when determining whether to use the context classloader.
>
>
> +1
>
> can anyone think of any reasons not to add this?
The only problem with adding a system property for this purpose
is that it would require granting the commons-digester jar the
permission to read it. It a web application bundles commons-digester
locally, it will not have this permission in most cases.
Perhaps it is safer to stick to the current "useContextClassLoader"
property and require that web applications always bundle
commons-digester, in which case the classloader that loaded
Digester.class will correspond to the web application's classloader,
which has access to all classes under WEB-INF/lib[classes].
Thanks,
Jan
>
>>Any comments appreciated.
>
>
> submit a patch :)
>
> - robert
>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
[digester] Re: Classloading regression between
commons-digester-1.0 and later versions
Posted by robert burrell donkin <ro...@blueyonder.co.uk>.
hi jan
please remember to add the subject prefix for the component.
On Thu, 2005-09-29 at 13:57 -0700, Jan Luehe wrote:
> This may be an old topic, but it seems a classloading regression was
> introduced between commons-digester-1.0 and later versions (including
> the most recent).
this is indeed a very old topic :)
<snip>
> Can someone explain to me the motivation for setting the
> "useContextClassLoader" property to FALSE by default?
i can offer you nothing more than the logs: it is set to FALSE by
default for no very good reason but most likely since it was felt
(rightly or wrongly) to preserve backwards compatibility.
> We can easily restore the commons-digester-1.0 behaviour in our own
> code by setting "useContextClassLoader" to TRUE on the Digester
> instances we acquire. However, this is not possible on "foreign" code
> that we bundle.
>
> It would be useful if Digester.getClassLoader() would also consider a
> system property (in addition to its own "useContextClassLoader"
> property) when determining whether to use the context classloader.
+1
can anyone think of any reasons not to add this?
> Any comments appreciated.
submit a patch :)
- robert
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Classloading regression between commons-digester-1.0 and later versions
Posted by Jan Luehe <Ja...@Sun.COM>.
This may be an old topic, but it seems a classloading regression was
introduced between commons-digester-1.0 and later versions (including
the most recent).
In commons-digester-1.0, a class was loaded as follows:
Class clazz = null;
// Check to see if the context class loader is set,
// and if so, use it, as it may be set in server-side
// environments and Class.forName() may cause issues
ClassLoader ctxLoader =
Thread.currentThread().getContextClassLoader();
if (ctxLoader == null) {
clazz = Class.forName(realClassName);
} else {
clazz = ctxLoader.loadClass(realClassName);
}
that is, if a context classloader had been set, it was used
(unconditionally).
In contrast, commons-digester-1.1 (and up) loads a class as follows:
Class clazz = digester.getClassLoader().loadClass(realClassName);
where Digester.getClassLoader() is implemented as follows:
/**
* Return the class loader to be used for instantiating application
objects
* when required. This is determined based upon the following rules:
* <ul>
* <li>The class loader set by <code>setClassLoader()</code>, if
any</li>
* <li>The thread context class loader, if it exists and the
* <code>useContextClassLoader</code> property is set to true</li>
* <li>The class loader used to load the Digester class itself.
* </ul>
*/
public ClassLoader getClassLoader() {
if (this.classLoader != null)
return (this.classLoader);
if (this.useContextClassLoader) {
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
if (classLoader != null)
return (classLoader);
}
return (this.getClass().getClassLoader());
}
that is, the context classloader is used only if it exists *AND*
the "useContextClassLoader" property has been set to TRUE. Unfortunately,
"useContextClassLoader" is FALSE by default, preventing the digester to
load any classes further down in the classloading hierarchy (e.g., in
WEB-INF/lib).
Can someone explain to me the motivation for setting the
"useContextClassLoader" property to FALSE by default?
We can easily restore the commons-digester-1.0 behaviour in our own
code by setting "useContextClassLoader" to TRUE on the Digester
instances we acquire. However, this is not possible on "foreign" code
that we bundle.
It would be useful if Digester.getClassLoader() would also consider a
system property (in addition to its own "useContextClassLoader"
property) when determining whether to use the context classloader.
Any comments appreciated.
Jan
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: Classloading regression between commons-digester-1.0 and later
versions
Posted by Jan Luehe <Ja...@Sun.COM>.
Simon Kitching wrote On 09/30/05 16:49,:
> It's not safe to put digester in the container path and expose this to
> components. Digester uses BeanUtils which uses lots of static variables.
> Any library that uses static variables is a very *bad* thing to place in
> a path that is shared by multiple supposedly independent components.
>
> I think that allowing a container to expose classes which are not part
> of the container specification is a really bad idea in any case:
> * http://wiki.apache.org/jakarta-commons/Logging/UndeployMemoryLeak
>
> Why do you have a need to expose digester to components rather than let
> components which want to use digester bundle it in WEB-INF/lib
> themselves?
What you suggest makes perfect sense.
Thanks!
Jan
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org
Re: Classloading regression between commons-digester-1.0 and later
versions
Posted by Simon Kitching <sk...@apache.org>.
On Thu, 2005-09-29 at 16:18 -0700, Jan Luehe wrote:
> Hi Craig,
>
> Craig McClanahan wrote On 09/29/05 15:44,:
> > Hi Jan :-),
> >
> > On 9/29/05, *Jan Luehe* <Jan.Luehe@sun.com <ma...@sun.com>>
> > wrote:
> >
> >
> > Can someone explain to me the motivation for setting the
> > "useContextClassLoader" property to FALSE by default?
> >
> > The motivation was this -- in a J2SE (now, Java SE) application, there
> > may not be a thread context class loader at all, or it might have
> > completely different semantics than what the EE specs require for a
> > servlet container's thread context class loader. It seemed safer to
> > avoid potential class loading mysteries to implement this as the default.
>
> thanks for your reply.
>
> Do you think it would have made sense for Digester to also consider
> a "useContextClassLoader" system property (which would be overridden
> by the Digester's "useContextClassLoader" property)?
>
> This would allow code that runs in an EE environment and relies on
> the digester being able to load classes from WEB-INF/lib to continue
> to work with later commons-digester versions, by setting the
> "useContextClassLoader" system property to TRUE. This would be useful
> in cases where one does not have any control over the code that
> acquires a digester.
>
It's not safe to put digester in the container path and expose this to
components. Digester uses BeanUtils which uses lots of static variables.
Any library that uses static variables is a very *bad* thing to place in
a path that is shared by multiple supposedly independent components.
I think that allowing a container to expose classes which are not part
of the container specification is a really bad idea in any case:
* http://wiki.apache.org/jakarta-commons/Logging/UndeployMemoryLeak
Why do you have a need to expose digester to components rather than let
components which want to use digester bundle it in WEB-INF/lib
themselves?
Regards,
Simon
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org
Re: Classloading regression between commons-digester-1.0 and later
versions
Posted by Jan Luehe <Ja...@Sun.COM>.
Hi Craig,
Craig McClanahan wrote On 09/29/05 15:44,:
> Hi Jan :-),
>
> On 9/29/05, *Jan Luehe* <Jan.Luehe@sun.com <ma...@sun.com>>
> wrote:
>
>
> Can someone explain to me the motivation for setting the
> "useContextClassLoader" property to FALSE by default?
>
> The motivation was this -- in a J2SE (now, Java SE) application, there
> may not be a thread context class loader at all, or it might have
> completely different semantics than what the EE specs require for a
> servlet container's thread context class loader. It seemed safer to
> avoid potential class loading mysteries to implement this as the default.
thanks for your reply.
Do you think it would have made sense for Digester to also consider
a "useContextClassLoader" system property (which would be overridden
by the Digester's "useContextClassLoader" property)?
This would allow code that runs in an EE environment and relies on
the digester being able to load classes from WEB-INF/lib to continue
to work with later commons-digester versions, by setting the
"useContextClassLoader" system property to TRUE. This would be useful
in cases where one does not have any control over the code that
acquires a digester.
Thanks,
Jan
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org
Re: Classloading regression between commons-digester-1.0 and later versions
Posted by Craig McClanahan <cr...@apache.org>.
Hi Jan :-),
On 9/29/05, Jan Luehe <Ja...@sun.com> wrote:
>
>
> Can someone explain to me the motivation for setting the
> "useContextClassLoader" property to FALSE by default?
The motivation was this -- in a J2SE (now, Java SE) application, there may
not be a thread context class loader at all, or it might have completely
different semantics than what the EE specs require for a servlet container's
thread context class loader. It seemed safer to avoid potential class
loading mysteries to implement this as the default.
Craig
Classloading regression between commons-digester-1.0 and later versions
Posted by Jan Luehe <Ja...@Sun.COM>.
This may be an old topic, but it seems a classloading regression was
introduced between commons-digester-1.0 and later versions (including
the most recent).
In commons-digester-1.0, a class was loaded as follows:
Class clazz = null;
// Check to see if the context class loader is set,
// and if so, use it, as it may be set in server-side
// environments and Class.forName() may cause issues
ClassLoader ctxLoader =
Thread.currentThread().getContextClassLoader();
if (ctxLoader == null) {
clazz = Class.forName(realClassName);
} else {
clazz = ctxLoader.loadClass(realClassName);
}
that is, if a context classloader had been set, it was used
(unconditionally).
In contrast, commons-digester-1.1 (and up) loads a class as follows:
Class clazz = digester.getClassLoader().loadClass(realClassName);
where Digester.getClassLoader() is implemented as follows:
/**
* Return the class loader to be used for instantiating application
objects
* when required. This is determined based upon the following rules:
* <ul>
* <li>The class loader set by <code>setClassLoader()</code>, if
any</li>
* <li>The thread context class loader, if it exists and the
* <code>useContextClassLoader</code> property is set to true</li>
* <li>The class loader used to load the Digester class itself.
* </ul>
*/
public ClassLoader getClassLoader() {
if (this.classLoader != null)
return (this.classLoader);
if (this.useContextClassLoader) {
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
if (classLoader != null)
return (classLoader);
}
return (this.getClass().getClassLoader());
}
that is, the context classloader is used only if it exists *AND*
the "useContextClassLoader" property has been set to TRUE. Unfortunately,
"useContextClassLoader" is FALSE by default, preventing the digester to
load any classes further down in the classloading hierarchy (e.g., in
WEB-INF/lib).
Can someone explain to me the motivation for setting the
"useContextClassLoader" property to FALSE by default?
We can easily restore the commons-digester-1.0 behaviour in our own
code by setting "useContextClassLoader" to TRUE on the Digester
instances we acquire. However, this is not possible on "foreign" code
that we bundle.
It would be useful if Digester.getClassLoader() would also consider a
system property (in addition to its own "useContextClassLoader"
property) when determining whether to use the context classloader.
Any comments appreciated.
Jan
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org
Re: commons-modeler and case sensitivity of property names
Posted by Jan Luehe <Ja...@Sun.COM>.
Simon,
Simon Kitching wrote:
> On Tue, 2005-06-28 at 17:21 -0700, Jan Luehe wrote:
>
>>Is there a way to have commons-modeler honor the case sensitivity of
>>Model MBean attribute (property) names?
>>
>>According to the JMX spec:
>>
>> All attribute and operation names derived from these design patterns
>> are case-sensitive. 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 my class that is instrumented as a Model MBean, I have getAbc() and
>>setAbc() methods, but when I declare "Abc" (instead of "abc") as the
>>attribute name in the associated mbeans-descriptor.xml, I get a
>>javax.management.AttributeNotFoundException
>>("Cannot find attribute abc").
>
>
> Can you provide details of where your spec quote can be found?
JMX 1.2 (http://www.jcp.org/en/jsr/detail?id=003), p.40 ("Case
Sensitivity").
> This seems to be in direct contradiction to the JavaBeans specification, and
> I would be rather surprised to see the two specs in such contradiction.
Yes, I've been surprised myself.
> Commons-modeller behaviour would seem to be complying fine with the
> JavaBeans spec.
Correct.
Jan
>
> Regards,
>
> Simon
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org
Re: commons-modeler and case sensitivity of property names
Posted by Jan Luehe <Ja...@Sun.COM>.
Simon,
Simon Kitching wrote:
> On Wed, 2005-06-29 at 12:32 +1200, Simon Kitching wrote:
>
>>On Tue, 2005-06-28 at 17:21 -0700, Jan Luehe wrote:
>>
>>>Is there a way to have commons-modeler honor the case sensitivity of
>>>Model MBean attribute (property) names?
>>>
>>>According to the JMX spec:
>>>
>>> All attribute and operation names derived from these design patterns
>>> are case-sensitive. 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 my class that is instrumented as a Model MBean, I have getAbc() and
>>>setAbc() methods, but when I declare "Abc" (instead of "abc") as the
>>>attribute name in the associated mbeans-descriptor.xml, I get a
>>>javax.management.AttributeNotFoundException
>>>("Cannot find attribute abc").
>>
>>Can you provide details of where your spec quote can be found? This
>>seems to be in direct contradiction to the JavaBeans specification, and
>>I would be rather surprised to see the two specs in such contradiction.
>>
>>Commons-modeller behaviour would seem to be complying fine with the
>>JavaBeans spec.
>
>
> Hmm..actually, my comments apply only when the java.beans.Introspector
> is using reflection + standard naming patterns to deduce what the
> properties of a bean are. When a BeanInfo class or similar mechanism is
> being used to explicitly define the properties I guess that you can have
> properties differing only by case of the initial letter, as the beaninfo
> specifies the getter and setter methods explicitly.
>
> The JMX spec quote above does seem to be talking about the introspection
> approach though, ie deducing the property names from the available
> getter/setter names. And this definitely does *not* support properties
> differing only by case of initial letter, as can be shown in a test:
>
> import java.beans.*;
> public class Foo {
> public static class MyBean {
> public void setBar(boolean b) {}
> public boolean getBar() {return false;}
> public boolean getbar() {return false;}
> }
> public static void main(String[] args) throws Exception {
> BeanInfo bi = Introspector.getBeanInfo(MyBean.class);
> PropertyDescriptor[] props = bi.getPropertyDescriptors();
> for(PropertyDescriptor pd : props) {
> System.out.println("name: " + pd.getName());
> System.out.println("read: " + pd.getReadMethod());
> System.out.println("write: " + pd.getWriteMethod());
> }
> }
> }
>
> Output:
> name: bar
> read: public boolean Foo$MyBean.getbar()
Notice this depends on the order in which the 2 getters are defined.
> write: public void Foo$MyBean.setBar(boolean)
> name: class
> read: public final native java.lang.Class java.lang.Object.getClass()
> write: null
>
> ie the standard javabeans introspector reports one property "bar" whose
> getter is "getbar" and whose setter is "setBar".
I found this in the mbeans-descriptor.dtd:
<!-- The "attribute" element describes a JavaBeans property of an
MBean. The following attributes are supported:
[...]
getMethod Name of the property getter method, if it does
not follow standard JavaBeans naming patterns.
[...]
setMethod Name of the property setter method, if it does
not follow standard JavaBeans naming patterns.
-->
which confirms our previous assumption about compliance with JavaBeans.
Still, it should be possible to declare (in mbeans-descriptor.xml)
attributes that only differ by case of initial letter (as supported by
the JMX spec), by specifying appropriate getters and setters, but for
some reason, it's not working for me.
I'll take a deeper look at the modeler sources.
Thanks for your help!
Jan
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org
Re: commons-modeler and case sensitivity of property names
Posted by Simon Kitching <sk...@apache.org>.
On Wed, 2005-06-29 at 12:32 +1200, Simon Kitching wrote:
> On Tue, 2005-06-28 at 17:21 -0700, Jan Luehe wrote:
> > Is there a way to have commons-modeler honor the case sensitivity of
> > Model MBean attribute (property) names?
> >
> > According to the JMX spec:
> >
> > All attribute and operation names derived from these design patterns
> > are case-sensitive. 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 my class that is instrumented as a Model MBean, I have getAbc() and
> > setAbc() methods, but when I declare "Abc" (instead of "abc") as the
> > attribute name in the associated mbeans-descriptor.xml, I get a
> > javax.management.AttributeNotFoundException
> > ("Cannot find attribute abc").
>
> Can you provide details of where your spec quote can be found? This
> seems to be in direct contradiction to the JavaBeans specification, and
> I would be rather surprised to see the two specs in such contradiction.
>
> Commons-modeller behaviour would seem to be complying fine with the
> JavaBeans spec.
Hmm..actually, my comments apply only when the java.beans.Introspector
is using reflection + standard naming patterns to deduce what the
properties of a bean are. When a BeanInfo class or similar mechanism is
being used to explicitly define the properties I guess that you can have
properties differing only by case of the initial letter, as the beaninfo
specifies the getter and setter methods explicitly.
The JMX spec quote above does seem to be talking about the introspection
approach though, ie deducing the property names from the available
getter/setter names. And this definitely does *not* support properties
differing only by case of initial letter, as can be shown in a test:
import java.beans.*;
public class Foo {
public static class MyBean {
public void setBar(boolean b) {}
public boolean getBar() {return false;}
public boolean getbar() {return false;}
}
public static void main(String[] args) throws Exception {
BeanInfo bi = Introspector.getBeanInfo(MyBean.class);
PropertyDescriptor[] props = bi.getPropertyDescriptors();
for(PropertyDescriptor pd : props) {
System.out.println("name: " + pd.getName());
System.out.println("read: " + pd.getReadMethod());
System.out.println("write: " + pd.getWriteMethod());
}
}
}
Output:
name: bar
read: public boolean Foo$MyBean.getbar()
write: public void Foo$MyBean.setBar(boolean)
name: class
read: public final native java.lang.Class java.lang.Object.getClass()
write: null
ie the standard javabeans introspector reports one property "bar" whose
getter is "getbar" and whose setter is "setBar".
NB: I'm not a commons-modeller maintainer.
Regards,
Simon
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org
Re: commons-modeler and case sensitivity of property names
Posted by Simon Kitching <sk...@apache.org>.
On Tue, 2005-06-28 at 17:21 -0700, Jan Luehe wrote:
> Is there a way to have commons-modeler honor the case sensitivity of
> Model MBean attribute (property) names?
>
> According to the JMX spec:
>
> All attribute and operation names derived from these design patterns
> are case-sensitive. 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 my class that is instrumented as a Model MBean, I have getAbc() and
> setAbc() methods, but when I declare "Abc" (instead of "abc") as the
> attribute name in the associated mbeans-descriptor.xml, I get a
> javax.management.AttributeNotFoundException
> ("Cannot find attribute abc").
Can you provide details of where your spec quote can be found? This
seems to be in direct contradiction to the JavaBeans specification, and
I would be rather surprised to see the two specs in such contradiction.
Commons-modeller behaviour would seem to be complying fine with the
JavaBeans spec.
Regards,
Simon
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org