4

I am using <p:selectCheckboxMenu> on a List<Long>:

<p:selectCheckboxMenu value="#{bean.selectedItems}">
    <f:selectItems value="#{bean.availableItems}" />
</p:selectCheckboxMenu>
private List<Long> selectedItems;
private Map<String, Long> availableItems;

When submitting the form and looping over the selected items as below,

for (int i = 0; i < selectedItems.size(); i++) {
    Long id = selectedItems.get(i);
    // ...
}

Then I get a class cast exception:

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
    at com.example.Bean.submit(Bean.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    ... 27 more

The same problem occurs with <p:selectManyCheckbox>, <p:selectManyMenu>, <h:selectManyMenu>, etc. All multiple-selection components basically. It works fine in <p:selectOneMenu> and all other single-selection components on a single value Long property.

How is this caused and how can I solve it?

2
  • can you share the content of your list because this code does not seem to prone to this exception Commented Nov 9, 2013 at 5:32
  • @ankit see my post. I edit and add picture Commented Nov 9, 2013 at 7:14

1 Answer 1

9

Your problem is caused by the following facts:

  1. Java generics are compiletime syntactic sugar and completely absent during runtime.
  2. EL expressions runs during runtime and not during compiletime.
  3. HTTP request parameters are obtained as Strings.

Logical consequence is: EL doesn't see any generic type information. EL doesn't see a List<Long>, but a List. So, when you don't explicitly specify a converter, EL will after obtaining the submitted value as String set it unmodified in the List by reflection means. When you attempt to cast it to Long afterwards during runtime, you'll obviously face a ClassCastException.

The solution is simple: explicitly specify a converter for String to Long. You can use the JSF builtin LongConverter for this which has the converter ID javax.faces.Long. Other builtin converters are listed here.

<p:selectCheckboxMenu ... converter="javax.faces.Long">

Another solution without the need to explicitly specify the converter is to change List<T> type to a T[]. This way the EL will see the Long typed array and thus perform automatic conversion. But this possibly requires changes elsewhere in the model which may not be desirable.

private Long[] selectedItems;

In case you're using a complex object (javabean, entity, POJO, etc) as select item value instead of a standard type like Long for which JSF has builtin converters, then the same rules also apply. You only need to create a custom Converter and explicitly specify it in input component's converter attribute, or rely on forClass if you can use T[]. How to create such a converter is elaborated in Conversion Error setting value for 'null Converter'.

Sign up to request clarification or add additional context in comments.

3 Comments

Hit ...I was looking one for answer..i didn't know that we can do it in JSF itself.
Saddly, only first workaround works well, looks like primefaces create a List and cant convert to array since Value not valid validation error is throw
The Validation Error: Value is not valid is elaborated here: stackoverflow.com/q/9069379

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.