myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Mike Kienenberger" <mkien...@gmail.com>
Subject Re: ERROR: Value is not a valid option
Date Wed, 04 Apr 2007 16:44:28 GMT
I'm not seeing how this will fix the problem.   In the test case you
posted, the value is not null -- it's empty string.  So checking
against null won't change the behavior.   The ClassCastException will
still occur.


On 4/3/07, fastbob <fastbob@gmail.com> wrote:
>
> After doing a bit of research, I'm convinced the problem only occurs when
> SelectItem.itemValue is an EJB. Given that 1.1.3 and the RI (1.2_04) do not
> have this problem, I suggest the current implementation be changed. If I'm
> wrong, please help me understand. Otherwise, I'll submit a change request.
>
> JSP contents:
>          <h:selectOneMenu id="client" value="#{myPage.projectType}"
> required="true">
>              <f:converter converterId="x.y.ProjectTypeConverter"/>
>              <f:selectItem itemValue="" itemLabel="--- Select Project
> Type---"/>
>              <f:selectItems value="#{myPage.projectTypeList}"/>
>          </h:selectOneMenu>
>
> Where ProjectTypeConverter returns null for "" on input and
> myPage.projectTypeList is a list of SelectItem created in the following
> manner:
>
>          ArrayList projectTypes = new ArrayList( projectTypeHome.findAll()
> );
>          for( int i = 0; i < projectTypes.size(); i++ )
>          {
>             ProjectTypeLocal projectType =
> (ProjectTypeLocal)projectTypes.get( i );
>             m_projectTypes.add( new SelectItem( projectType,
> projectType.getName() ) );
>          }
>
> Note that the SelectItem.itemValue is an EJB.
>
> The intent is to force the user to select a value from the list. If no
> action is taken by the user, generate an error. This is directly analogous
> to a Tomahawk example, except the values are EJB's.
>
> The problem:
> This worked fine under MyFaces 1.1.3 and appears that it would work under RI
> 1.2_04. Under release 1.1.5, however, a ClassCastException occurs during the
> validation phase, but only if a list item is selected and the item is an
> EJB.
>
> Analysis (based on 1.1.5 release):
> During the validation phase, UISelectOne.validateValue is invoked with the
> selected EJB. This causes the following lines in
> _SelectItemsUtil.matchValue() to be invoked:
>
>                 [item is class SelectItem]
>                 Object itemValue = item.getValue();
>                 if (value==itemValue || value.equals(itemValue))
>
> This is fine for the SelectItem values that are EJB's, but not for "". Since
> EJB equality requires identity, the EJB equals() method calls isIdentical()
> and immediately encounters an exception casting to EJBLocalObject (code here
> from JBoss 4.0.4GA LocalProxy):
>
>    Boolean isIdentical(final Object a, final Object b)
>    {
>       final EJBLocalObject ejb = (EJBLocalObject)a;
>       Boolean isIdentical = Boolean.FALSE;
>       if( ejb != null )
>       {
>          isIdentical = new Boolean(ejb.toString().equals(b));
>       }
>       return isIdentical;
>    }
>
> Possible solution:
> Iin _SelectItemsUtil.matchValue() change the lines above to:
>
>                 [item is class SelectItem]
>                 Object itemValue = item.getValue();
>                 if (value==itemValue || ( itemValue != null &&
> itemValue.equals(value)))
>
>
>
>
> fastbob wrote:
> >
> > Usually the selectItem values are EJB's, but in a couple of instances they
> > strings that just happen to be the serialized form of the EJB. The
> > prototypical code looks like:
> >
> >          ArrayList projectTypes = new ArrayList( projectTypeHome.findAll()
> > );
> >          for( int i = 0; i < projectTypes.size(); i++ )
> >          {
> >             ProjectTypeLocal projectType =
> > (ProjectTypeLocal)projectTypes.get( i );
> >             m_projectTypes.add( new SelectItem( projectType,
> > projectType.getName() ) );
> >          }
> >
> > What this means is when we get to the following lines in _SelectItemsUtil,
> > the equals() method of the EJB is called with the empty ("") string (in
> > 1.1.5):
> >
> >                  [item is class SelectItem]
> >                  Object itemValue = item.getValue();
> >                  if (value==itemValue || value.equals(itemValue))
> >
> > It appears that the 1.1.3 code handled the case of any String being
> > passed. Since our converters look for an empty string, this results in the
> > EJB equals() being passed null:
> >
> >                 Object itemValue = item.getValue();
> >                 if(converter != null && itemValue instanceof String)
> >                 {
> >                     itemValue = converter.getConvertedValue(context,
> > (String)itemValue);
> >                 }
> >                 if (value==itemValue || value.equals(itemValue))
> >
> > But I guess this circles back to non-standard conversion that was taken
> > out.
> >
> > I'm pretty ignorant of all the JSF lifecycle semantics, but since this
> > practice is always used with required="true", would an earlier check for a
> > non-null, non-empty string fix this?
> >
> > I'm open to suggestions.
> >
> >
> > Mike Kienenberger wrote:
> >>
> >> Yes, I think you're right.  It's not the form String -> Object that's
> >> causing the issue.
> >> It looks like it's the contents of the selectItem values.  What are
> >> you initializing the selectItem value fields with?
> >>
> >> What's the contents of selectItem.value when it's of type String?
> >>
> >>
> >
> >
>
> --
> View this message in context: http://www.nabble.com/ERROR%3A-Value-is-not-a-valid-option-tf3270984.html#a9826625
> Sent from the MyFaces - Users mailing list archive at Nabble.com.
>
>

Mime
View raw message