You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Erik Gustavson <go...@gmail.com> on 2005/06/12 03:46:47 UTC
managed map properties - bug or spec loophole?
I've been playing around with managed properties recently and noticed some
behavior that I did not quite expect when using map-entries against a Map
property on my managed bean.
If I create a set of map values like this, everything works fine and I get
my values in a map in my managed bean.
....
<managed-property>
<property-name>someMapping</property-name>
<map-entries>
<map-entry>
<key>key1</key>
<value>value1</value>
</map-entry>
<map-entry>
<key>key2</key>
<value>value2</value>
</map-entry>
</map-entries>
</managed-property>
....
However, I decided I wanted my values to be sorted, so I added in a line to
specify the exact type of Map (TreeMap) class I wanted to be created for me:
....
<managed-property>
<property-name>someMapping</property-name>
<property-class>java.util.TreeMap</property-class>
<map-entries>
<map-entry>
<key>key1</key>
<value>value1</value>
</map-entry>
<map-entry>
<key>key2</key>
<value>value2</value>
</map-entry>
</map-entries>
</managed-property>
....
When MyFaces attempt to create my bean, it blows up trying to coerce a
HashMap to a TreeMap (see stack trace at end of email). Looking through the
code, I can see that in ManagedBeanBuilder.initializeProperties the value is
being created as a HashMap. To me, this looks like a bug... the value should
be created as a HashMap only if the property's Class value is not set (and
if it's type is set to a non-Map, an class-cast exception would be thrown)
something like:
case ManagedProperty.TYPE_MAP:
if (property.getPropertyClass != null) {
Class mapClass = ClassUtils.simpleJavaTypeToClass(property.getPropertyClass
());
value = mapClass.newInstance();
} else {
value = new HashMap();
}
initializeMap(facesContext, property.getMapEntries(), (Map) value);
break;
etc... etc... same would probably go for Lists as well.
Any thoughts on this? I'm not an expert of the JSF spec - is there any
mention about if its legal to combine map-entries with a specific property
class in your faces config xml?
--- Stack Trace Below ------------
Caused by: javax.faces.FacesException: Cannot coerce java.util.HashMap to
java.util.TreeMap
at org.apache.myfaces.util.ClassUtils.convertToType(ClassUtils.java:321)
at org.apache.myfaces.config.ManagedBeanBuilder.initializeProperties(
ManagedBeanBuilder.java:150)
at org.apache.myfaces.config.ManagedBeanBuilder.buildManagedBean(
ManagedBeanBuilder.java:63)
at org.apache.myfaces.el.VariableResolverImpl.resolveVariable(
VariableResolverImpl.java:328)
at org.apache.myfaces.el.ValueBindingImpl$ELVariableResolver.resolveVariable
(ValueBindingImpl.java:637)
at org.apache.commons.el.NamedValue.evaluate(NamedValue.java:124)
at org.apache.commons.el.ComplexValue.evaluate(ComplexValue.java:140)
at org.apache.myfaces.el.ValueBindingImpl.getValue(ValueBindingImpl.java
:441)
... 42 more
Caused by: javax.servlet.jsp.el.ELException: Attempt to coerce a value of
type "java.util.HashMap" to type "java.util.TreeMap"
at org.apache.commons.el.Logger.logError(Logger.java:481)
at org.apache.commons.el.Logger.logError(Logger.java:498)
at org.apache.commons.el.Logger.logError(Logger.java:566)
at org.apache.commons.el.Coercions.coerceToObject(Coercions.java:799)
at org.apache.commons.el.Coercions.coerce(Coercions.java:343)
at org.apache.myfaces.util.ClassUtils.convertToType(ClassUtils.java:314)
... 49 more
Re: managed map properties - bug or spec loophole?
Posted by Martin Marinschek <ma...@gmail.com>.
Ok, it's been some time, but I have implemented your suggestion...
try it out in SVN-Head (or the nightly build)...
I think that you are right, even if the spec is not clear about that
issue, it might be nice for the users to have that feature.
regards,
Martin
On 6/12/05, Erik Gustavson <go...@gmail.com> wrote:
> I've been playing around with managed properties recently and noticed some
> behavior that I did not quite expect when using map-entries against a Map
> property on my managed bean.
>
> If I create a set of map values like this, everything works fine and I get
> my values in a map in my managed bean.
>
> ....
> <managed-property>
> <property-name>someMapping</property-name>
> <map-entries>
> <map-entry>
> <key>key1</key>
> <value>value1</value>
> </map-entry>
> <map-entry>
> <key>key2</key>
> <value>value2</value>
> </map-entry>
> </map-entries>
> </managed-property>
> ....
>
> However, I decided I wanted my values to be sorted, so I added in a line to
> specify the exact type of Map (TreeMap) class I wanted to be created for me:
>
> ....
> <managed-property>
> <property-name>someMapping</property-name>
> <property-class>java.util.TreeMap</property-class>
> <map-entries>
> <map-entry>
> <key>key1</key>
> <value>value1</value>
> </map-entry>
> <map-entry>
> <key>key2</key>
> <value>value2</value>
> </map-entry>
> </map-entries>
> </managed-property>
> ....
>
> When MyFaces attempt to create my bean, it blows up trying to coerce a
> HashMap to a TreeMap (see stack trace at end of email). Looking through the
> code, I can see that in
> ManagedBeanBuilder.initializeProperties the value is being
> created as a HashMap. To me, this looks like a bug... the value should be
> created as a HashMap only if the property's Class value is not set (and if
> it's type is set to a non-Map, an class-cast exception would be thrown)
>
> something like:
>
> case ManagedProperty.TYPE_MAP:
> if (property.getPropertyClass != null) {
> Class mapClass =
> ClassUtils.simpleJavaTypeToClass(property.getPropertyClass());
> value = mapClass.newInstance();
> } else {
> value = new HashMap();
> }
>
> initializeMap(facesContext, property.getMapEntries(),
> (Map) value);
> break;
>
> etc... etc... same would probably go for Lists as well.
>
> Any thoughts on this? I'm not an expert of the JSF spec - is there any
> mention about if its legal to combine map-entries with a specific property
> class in your faces config xml?
>
>
> --- Stack Trace Below ------------
>
> Caused by: javax.faces.FacesException: Cannot coerce java.util.HashMap to
> java.util.TreeMap
> at
> org.apache.myfaces.util.ClassUtils.convertToType(ClassUtils.java:321)
> at
> org.apache.myfaces.config.ManagedBeanBuilder.initializeProperties(ManagedBeanBuilder.java:150)
> at
> org.apache.myfaces.config.ManagedBeanBuilder.buildManagedBean(ManagedBeanBuilder.java:63)
> at
> org.apache.myfaces.el.VariableResolverImpl.resolveVariable(VariableResolverImpl.java:328)
> at
> org.apache.myfaces.el.ValueBindingImpl$ELVariableResolver.resolveVariable(ValueBindingImpl.java:637)
> at
> org.apache.commons.el.NamedValue.evaluate(NamedValue.java:124)
> at
> org.apache.commons.el.ComplexValue.evaluate(ComplexValue.java:140)
> at
> org.apache.myfaces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:441)
> ... 42 more
> Caused by: javax.servlet.jsp.el.ELException: Attempt to
> coerce a value of type "java.util.HashMap" to type "java.util.TreeMap"
> at
> org.apache.commons.el.Logger.logError(Logger.java:481)
> at
> org.apache.commons.el.Logger.logError(Logger.java:498)
> at
> org.apache.commons.el.Logger.logError(Logger.java:566)
> at
> org.apache.commons.el.Coercions.coerceToObject(Coercions.java:799)
> at
> org.apache.commons.el.Coercions.coerce(Coercions.java:343)
> at
> org.apache.myfaces.util.ClassUtils.convertToType(ClassUtils.java:314)
> ... 49 more
>
>
>
>
>