Open a JIRA with a simple example, and I'll take a look (unless
someone else beats me to it).

At first glance, I think you're probably right -- we need to handle
the case that itemValue might be null.  I wonder why I haven't hit an
issue with this yet?




On 4/3/07, fastbob <[EMAIL PROTECTED]> 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.


Reply via email to