BlazeDS custom serialization causes RangeError

872 views Asked by At

I am using BlazeDS to communicate between Java and Flash/Flex. And everything works fine, except that Java Null Integer becomes 0 on Flex side.

To handle the problem with transferring a Java Null Integer to an Flash/Flex int, I have implement a custom serialization, which works on the Java side and uses negative values to express Null values.

After implementing that I get an

RangeError: Error #2006: Der angegebene Index liegt außerhalb des zulässigen Bereichs.
(in english: the index is out of range)
                at ObjectInput/readObject()
                at mx.collections::ArrayList/readExternal()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ArrayList.as:586]
                at mx.collections::ArrayCollection/readExternal()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ArrayCollection.as:147]
                at ObjectInput/readObject()
                at mx.messaging.messages::AbstractMessage/readExternal()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\messages\AbstractMessage.as:486]
                at mx.messaging.messages::AsyncMessage/readExternal()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\messages\AsyncMessage.as:170]
                at mx.messaging.messages::AcknowledgeMessage/readExternal()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\messages\AcknowledgeMessage.as:95]

The exception occures on the Flex side while deserializing the Java Result. Which is an list of complex objects which contains this special class with the custom serialization. Because there was no such problem until I added the custom serialization, I guess it must belong to the problem, but i have no clue what triggers the exception.

This is the code of the object with the custom serialization:

package crux.domain.dto;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;

public class NullAbleID implements Serializable, Externalizable {

    private static final long serialVersionUID = 788620879056753289L;

    private Integer id;

    public NullAbleID() {
        super();
        this.id = null;
    }

    public NullAbleID(final Integer id) {
        this.id = id;
    }

    getter, setter for ID and hashCode and equals

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {        
        out.writeObject(this.nullToNegative(this.id));                
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException {
        this.id = this.negativeToNull(in.readInt());
    }

    private int nullToNegative(Integer id) {
        if (id == null) {
            return -1;
        } else {        
            return id.intValue();
        }
    }

    private Integer negativeToNull(int flashId) {
        if (flashId < 0) {
            return null;
        } else {
            return Integer.valueOf(flashId);
        }
    }
}

Flex: two classes, because we use Gas3 Granite Data Service code generation:

/**
* Generated by Gas3 v2.1.0 (Granite Data Services).
*
*/
package crux.domain.dto {

    import flash.utils.IExternalizable;

    [Bindable]
    public class NullAbleIDBase {

        public function NullAbleIDBase() {}


        private var _id:Number;

        public function set id(value:Number):void {
            _id = value;
        }
        public function get id():Number {
            return _id;
        }
    }
}

Flex sub class with read and write external

package crux.domain.dto {

      import flash.utils.IDataInput;
      import flash.utils.IDataOutput;
      import flash.utils.IExternalizable;

    [Bindable]
    [RemoteClass(alias="crux.domain.dto.NullAbleID")]
    public class NullAbleID extends NullAbleIDBase implements IExternalizable{

            public function readExternal(input:IDataInput):void {
                  id = input.readInt();
            }

            public function writeExternal(output:IDataOutput):void {
                  output.writeInt(id);
            }
    }
}

I have spend several hours on this problem, but I have no idea what the problem is. Do you see the cause for the exception?

1

There are 1 answers

1
JB Nizet On BEST ANSWER

Not sure it's the cause of the problem, because I don't know BlazeDS, but the methods readExternal and writeExternal of your NullAbleID class are not symetric : you write an object of type Integer in writeExternal, and you read an int in readExternal.