Uploaded image for project: 'ZK'
  1. ZK
  2. ZK-1960

save binding to an array throws ClassCastException

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Normal
    • Resolution: Fixed
    • Affects Version/s: 6.5.4
    • Fix Version/s: 6.5.5
    • Component/s: Databind 2
    • Security Level: Jimmy

      Description

      this fiddle http://zkfiddle.org/sample/skqfup/4-Array-binding-bug#source-1 demonstrates a simple case to reproduce this

      The values are loaded correctly, but saving them fails, throwing this exception (trying to convert the array index into a property name)

      Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
      at org.zkoss.bind.xel.zel.BindELResolver.tieValue(BindELResolver.java:168)
      at org.zkoss.bind.xel.zel.BindELResolver.setValue(BindELResolver.java:105)
      at org.zkoss.zel.impl.parser.AstValue.setValue(AstValue.java:249)
      at org.zkoss.zel.impl.ValueExpressionImpl.setValue(ValueExpressionImpl.java:247)
      at org.zkoss.xel.zel.ELXelExpression.setValue(ELXelExpression.java:50)
      at org.zkoss.bind.impl.BindEvaluatorXImpl.setValue(BindEvaluatorXImpl.java:58)
      ... 34 more

        Activity

        Hide
        cor3000 cor3000 added a comment - - edited

        using model and templates also fails with the same error

        inVM

        public ListModel<String> getTestArrayListModel() {
        	return new ListModelList<String>(testArray);
        }
        

        in zul

        <grid hflex="1" model="@load(vm.testArrayListModel)">
        	<columns>
        		<column />
        	</columns>
        	<template name="model">
        		<row>
        			<textbox value="@bind(each)" />
        		</row>
        	</template>
        </grid>
        
        Show
        cor3000 cor3000 added a comment - - edited using model and templates also fails with the same error inVM public ListModel< String > getTestArrayListModel() { return new ListModelList< String >(testArray); } in zul <grid hflex= "1" model= "@load(vm.testArrayListModel)" > <columns> <column /> </columns> <template name= "model" > <row> <textbox value= "@bind(each)" /> </row> </template> </grid>
        Hide
        cor3000 cor3000 added a comment - - edited

        workarounds:
        1.) wrap the Array in an Object with named getters/setters for the indices.

        getVal0() {
          return array[0];
        }
        setVal0(String value) {
          array[0] = value;
        }
        

        use these properties in the @bind annotations e.g. @bind(vm.wrapper.val0)

        2.) instead of save binding use the onChange event to send a command to set the value in the array

        <textbox value="@load(vm.testArray[0])" 
          onChange="@command('changeArrayValue', array=vm.testArray, index=0, newValue=event.value)" />
        

        and in VM:

        @Command("changeArrayValue")
        public void onChangeArrayValue(@BindingParam("array") String[] array,
        		@BindingParam("index") int index,
        		@BindingParam("newValue") String newValue) {
        	array[index] = newValue;
        	BindUtils.postNotifyChange(null, null, this, "testArray");
        }
        

        3.) use @bind(vm.testArray['0']) - with apostrophes around the index - instead of @bind(vm.testArray[0])

        Show
        cor3000 cor3000 added a comment - - edited workarounds: 1.) wrap the Array in an Object with named getters/setters for the indices. getVal0() { return array[0]; } setVal0( String value) { array[0] = value; } use these properties in the @bind annotations e.g. @bind(vm.wrapper.val0) 2.) instead of save binding use the onChange event to send a command to set the value in the array <textbox value= "@load(vm.testArray[0])" onChange= "@command('changeArrayValue', array=vm.testArray, index=0, newValue=event.value)" /> and in VM: @Command( "changeArrayValue" ) public void onChangeArrayValue(@BindingParam( "array" ) String [] array, @BindingParam( "index" ) int index, @BindingParam( "newValue" ) String newValue) { array[index] = newValue; BindUtils.postNotifyChange( null , null , this , "testArray" ); } 3.) use @bind(vm.testArray ['0'] ) - with apostrophes around the index - instead of @bind(vm.testArray [0] )
        Hide
        dennis dennis added a comment -

        fixed since 2013/10/8

        Show
        dennis dennis added a comment - fixed since 2013/10/8
        Hide
        cor3000 cor3000 added a comment -

        the issue mentioned in the first comment was not yet addressed

        Show
        cor3000 cor3000 added a comment - the issue mentioned in the first comment was not yet addressed
        Hide
        dennis dennis added a comment -

        get following in model case when save back.

        SEVERE: >>org.zkoss.zk.ui.UiException: Property '2' not found on type org.zkoss.zul.ListModelArray at [file:/D:/workspace/support/zksupport/src/main/webapp/customer/vdl/testArray.zul, line:33]
        >>org.zkoss.zel.PropertyNotFoundException: Property '2' not found on type org.zkoss.zul.ListModelArray
        >> at org.zkoss.zel.BeanELResolver$BeanProperties.get(BeanELResolver.java:298)
        >> at org.zkoss.zel.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:249)
        >> at org.zkoss.zel.BeanELResolver.property(BeanELResolver.java:423)
        >> at org.zkoss.zel.BeanELResolver.setValue(BeanELResolver.java:135)
        >> at org.zkoss.zel.CompositeELResolver.setValue(CompositeELResolver.java:81)
        >> at org.zkoss.zel.CompositeELResolver.setValue(CompositeELResolver.java:81)
        >> at org.zkoss.xel.zel.XelELResolver.setValue(XelELResolver.java:114)
        >> at org.zkoss.bind.xel.zel.BindELResolver.setValue(BindELResolver.java:104)
        >> at org.zkoss.zel.impl.parser.AstValue.setValue(AstValue.java:249)
        >> at org.zkoss.zel.impl.ValueExpressionImpl.setValue(ValueExpressionImpl.java:247)
        >> at org.zkoss.xel.zel.ELXelExpression.setValue(ELXelExpression.java:50)
        >> at org.zkoss.bind.impl.BindEvaluatorXImpl.setValue(BindEvaluatorXImpl.java:58)
        >> at org.zkoss.bind.impl.ReferenceBindingImpl.se
        
        Show
        dennis dennis added a comment - get following in model case when save back. SEVERE: >>org.zkoss.zk.ui.UiException: Property '2' not found on type org.zkoss.zul.ListModelArray at [file:/D:/workspace/support/zksupport/src/main/webapp/customer/vdl/testArray.zul, line:33] >>org.zkoss.zel.PropertyNotFoundException: Property '2' not found on type org.zkoss.zul.ListModelArray >> at org.zkoss.zel.BeanELResolver$BeanProperties.get(BeanELResolver.java:298) >> at org.zkoss.zel.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:249) >> at org.zkoss.zel.BeanELResolver.property(BeanELResolver.java:423) >> at org.zkoss.zel.BeanELResolver.setValue(BeanELResolver.java:135) >> at org.zkoss.zel.CompositeELResolver.setValue(CompositeELResolver.java:81) >> at org.zkoss.zel.CompositeELResolver.setValue(CompositeELResolver.java:81) >> at org.zkoss.xel.zel.XelELResolver.setValue(XelELResolver.java:114) >> at org.zkoss.bind.xel.zel.BindELResolver.setValue(BindELResolver.java:104) >> at org.zkoss.zel.impl.parser.AstValue.setValue(AstValue.java:249) >> at org.zkoss.zel.impl.ValueExpressionImpl.setValue(ValueExpressionImpl.java:247) >> at org.zkoss.xel.zel.ELXelExpression.setValue(ELXelExpression.java:50) >> at org.zkoss.bind.impl.BindEvaluatorXImpl.setValue(BindEvaluatorXImpl.java:58) >> at org.zkoss.bind.impl.ReferenceBindingImpl.se
        Hide
        dennis dennis added a comment -

        fixed 2nd issue on 2013/10/9

        Show
        dennis dennis added a comment - fixed 2nd issue on 2013/10/9
        Hide
        vincentjian vincentjian added a comment - - edited

        Still have this issue when saving. Check the updated zkfiddle sample and test in ZK 6.5.4 (working fine in ZK 7.0.0).
        http://zkfiddle.org/sample/skqfup/7-Array-binding-bug

        Here is the Stacktrace in ZK 6.5.4

        SEVERE: java.lang.Long cannot be cast to java.lang.String at [file:/D:/SVN/cht/cht-samples/src/main/webapp/issues/testZK-1960-1.zul, line:15]
        >>java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
        >>	at org.zkoss.bind.xel.zel.BindELResolver.tieValue(BindELResolver.java:168)
        >>	at org.zkoss.bind.xel.zel.BindELResolver.setValue(BindELResolver.java:105)
        >>	at org.zkoss.zel.impl.parser.AstValue.setValue(AstValue.java:249)
        >>	at org.zkoss.zel.impl.ValueExpressionImpl.setValue(ValueExpressionImpl.java:247)
        >>	at org.zkoss.xel.zel.ELXelExpression.setValue(ELXelExpression.java:50)
        >>	at org.zkoss.bind.impl.BindEvaluatorXImpl.setValue(BindEvaluatorXImpl.java:58)
        >>	at org.zkoss.bind.impl.SavePropertyBindingImpl.save(SavePropertyBindingImpl.java:148)
        >>	at org.zkoss.bind.impl.PropertyBindingHandler.doSaveBinding(PropertyBindingHandler.java:148)
        >>	at org.zkoss.bind.impl.PropertyBindingHandler.doSaveEvent(PropertyBindingHandler.java:203)
        >>	at org.zkoss.bind.impl.BinderImpl.doSaveEvent(BinderImpl.java:1618)
        
        Show
        vincentjian vincentjian added a comment - - edited Still have this issue when saving. Check the updated zkfiddle sample and test in ZK 6.5.4 (working fine in ZK 7.0.0). http://zkfiddle.org/sample/skqfup/7-Array-binding-bug Here is the Stacktrace in ZK 6.5.4 SEVERE: java.lang. Long cannot be cast to java.lang. String at [file:/D:/SVN/cht/cht-samples/src/main/webapp/issues/testZK-1960-1.zul, line:15] >>java.lang.ClassCastException: java.lang. Long cannot be cast to java.lang. String >> at org.zkoss.bind.xel.zel.BindELResolver.tieValue(BindELResolver.java:168) >> at org.zkoss.bind.xel.zel.BindELResolver.setValue(BindELResolver.java:105) >> at org.zkoss.zel.impl.parser.AstValue.setValue(AstValue.java:249) >> at org.zkoss.zel.impl.ValueExpressionImpl.setValue(ValueExpressionImpl.java:247) >> at org.zkoss.xel.zel.ELXelExpression.setValue(ELXelExpression.java:50) >> at org.zkoss.bind.impl.BindEvaluatorXImpl.setValue(BindEvaluatorXImpl.java:58) >> at org.zkoss.bind.impl.SavePropertyBindingImpl.save(SavePropertyBindingImpl.java:148) >> at org.zkoss.bind.impl.PropertyBindingHandler.doSaveBinding(PropertyBindingHandler.java:148) >> at org.zkoss.bind.impl.PropertyBindingHandler.doSaveEvent(PropertyBindingHandler.java:203) >> at org.zkoss.bind.impl.BinderImpl.doSaveEvent(BinderImpl.java:1618)
        Hide
        vincentjian vincentjian added a comment -

        Change fix version to 6.5.5

        Show
        vincentjian vincentjian added a comment - Change fix version to 6.5.5

          People

          • Assignee:
            Jenkins Jenkins
            Reporter:
            cor3000 cor3000
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: