Thanks Jakob.
This is a clear statement and I will change my impl instead of debugging 
frameworks.
The converter was just a desperate approach.

But this is another compability issue which I can’t really understand.
It is working with JSF 1.1, is not working with JSF 1.2 and will be working 
again in JSF 2.
This makes updates cumbersome.

So long,
Michael


From: [email protected] [mailto:[email protected]] On Behalf Of 
Jakob Korherr
Sent: Freitag, 18. Dezember 2009 13:27
To: MyFaces Discussion
Cc: Michael Heinen
Subject: Re: conversion error in selectmanyCheckbox - IllegalArgumentException 
- Cannot convert java.util.ArrayList

Hi Michael,

The problem is that the <h:selectManyCheckbox> creates a new ArrayList (or 
array depending on the type of the property) every time you submit it. You 
cannot tell it to use another implementation of List in JSF 1.2. However, it 
will be possible in JSF 2.0 (actually I implemented this functionality on 
MyFaces).

You have to use ArrayList<String> on your bean property. However, you can 
create a new ArrayListWithSeparator in your setter method and invoke addAll() 
passing the ArrayList as an argument.

The converter approach is totally wrong, sorry.

Regards,
Jakob
2009/12/18 Michael Heinen 
<[email protected]<mailto:[email protected]>>
Hi,

I have another migration problem and cannot solve it so far.

One of my selectManyCheckboxes is not working anymore. A Conversion error is 
thrown after form submission:

SCHWERWIEGEND: Cannot convert [soccer, tennis] of type class 
java.util.ArrayList to class 
com.recommind.litigation.client.web.model.utils.ArrayListWithSeparator
java.lang.IllegalArgumentException: Cannot convert [soccer, tennis] of type 
class java.util.ArrayList to class 
com.recommind.litigation.client.web.model.utils.ArrayListWithSeparator
               at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:375)
               at org.apache.el.parser.AstValue.setValue(AstValue.java:141)
               at 
org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:249)
               at 
org.apache.jasper.el.JspValueExpression.setValue(JspValueExpression.java:85)
               at 
javax.faces.component._ValueExpressionToValueBinding.setValue(_ValueExpressionToValueBinding.java:124)
               at javax.faces.component.UIInput.updateModel(UIInput.java:282)
               at javax.faces.component.UIInput.processUpdates(UIInput.java:219)
               at 
javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:746)
               at 
org.apache.myfaces.custom.datalist.AbstractHtmlDataList.process(AbstractHtmlDataList.java:171)
               at 
org.apache.myfaces.custom.datalist.AbstractHtmlDataList.processChildren(AbstractHtmlDataList.java:150)
               at 
org.apache.myfaces.custom.datalist.AbstractHtmlDataList.processUpdates(AbstractHtmlDataList.java:95)
               at 
javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:746)
               at 
org.apache.myfaces.custom.aliasbean.AliasBeansScope.processUpdates(AliasBeansScope.java:222)
               at 
javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:746)
               at 
javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:746)
               at 
javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:746)
               at 
javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:746)
               at 
javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:746)
               at 
org.ajax4jsf.component.UIAjaxRegion.processUpdates(UIAjaxRegion.java:138)
               at 
org.ajax4jsf.component.AjaxViewRoot$2.invokeContextCallback(AjaxViewRoot.java:424)
               at 
org.ajax4jsf.component.ContextCallbackWrapper.invokeContextCallback(ContextCallbackWrapper.java:44)
               at 
javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:163)

This worked well with JSF 1.1 of course.

JSP:
<t:dataList id="cpTList"
           value="#{AController.links}"
           var="cpLink"
           layout="simple">
 <h:selectManyCheckbox id="cboxCPsel"
                       rendered="#{cpLink.typeSelectManyCheckBox }"
                       layout="pageDirection"
                       
value="#{ProxyController.activeWController.previewDocument.attributes[cpLink.name]}">
   <f:selectItems 
value="#{ProxyController.activeWController.scoredCategories[cpLink.name]}"/>
 </h:selectManyCheckbox>

previewDocument contains a Map with attributes.
The value here is of type ArrayListWithSeparator which is a subclass of 
ArrayList with an overwritten toString() method.

So I tried to add a converter:
<converter>
 <converter-id>qqqq</converter-id>
 <--<converter-for-class>com.foo.ArrayListWithSeparator</converter-for-class>-->
 
<converter-class>com.foo.converters.ArrayListWithSeparatorConverter</converter-class>
</converter>

This converter is created and called if I specify it via ID and the converter 
attribute.
The converter is not called via converter-class definition which is strange at 
first sight.

Method getAsObject is called but I get A ClassCastException now:

public String getAsString(FacesContext context, UIComponent component, Object 
value) throws ConverterException
{
   ArrayListWithSeparator<String> list = (ArrayListWithSeparator<String>) value;

Problem:  value is of type String and cannot be cast to a 
ArrayListWithSeparator.

CallStack:
ArrayListWithSeparatorConverter.getAsString(FacesContext, UIComponent, Object) 
line: 81
RendererUtils.getConvertedStringValue(FacesContext, UIComponent, Converter, 
Object) line: 648
RendererUtils.internalSubmittedOrSelectedValuesAsSet(FacesContext, UIComponent, 
Converter, UISelectMany, Object) line: 709

The converter is called of every list member in line 709:

       for (Iterator i = lst.iterator(); i.hasNext();)
               set.add(getConvertedStringValue(context, component, converter, 
i.next()));

Dead end! It seems to me that a custom converter does not help here.

Now I changed the EL expression. It works with JSF 1.2 with following 
expression without any converters:
value="#{ProxyController.activeWController.dummies}"

activeWController:
public ArrayListWithSeparator<String> getDummies(){
 return (ArrayListWithSeparator<String>) 
this.mPreviewDocument.getAttribute("foo");
}
public void setDummies(ArrayListWithSeparator<String> sis){
 this.mPreviewDocument.addAttribute("foo", sis);
}

The same instances are accessed!!! What's that?
The instance passed into setDummies is of class ArrayList, not of class 
ArrayListWithSeparator!


So this is another sample which is not working with JSF 1.2 and the new Unified 
EL!
I spent many many hours with this and don't get it running and don't have any 
ideas.

Updated Libs and environment:
myFaces from 1.1.6 to 1.2.8
tomahawk from 1.1.7 to tomahawk12-1.1.9
richfaces from 3.1.5 to 3.3.3 beta (api,impl and ui)
tiles from 1 to 2.0.5
Tomcat 6.0.20

Questions:
1) Why do I get this IllegalArgumentException regarding failed conversion from 
class ArrayList into ArrayListWithSeparator with JSF 1.2 and Unified EL?
2) Can I do anything with a converter here or is this a totally wrong approach?
3) Why is this working with my getDummies and setDummies method and why is an 
instance of ArrayList passed into the setter instead an ArrayListWithSeparator?

Any help is highly appreciated
Michael

Reply via email to