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?
Not sure it's the cause of the problem, because I don't know BlazeDS, but the methods
readExternal
andwriteExternal
of yourNullAbleID
class are not symetric : you write an object of type Integer inwriteExternal
, and you read an int inreadExternal
.