Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EncodeableDesc readFieldInfoFromClass() method error when field is an array of IEncodeable #188

Open
riccardobellini opened this issue Jan 9, 2019 · 0 comments

Comments

@riccardobellini
Copy link

Hi,
I am trying to decode an ExtensionObject which represents a complex Structure by means of the EncodeableReflectionSerializer. I have already registered all the IEncodeable classes that are part of the complex structure definition in the EncodeableDescTable by using the EncodeableDesc::readFromClass() method, but there seems to be a problem with a field which is an array of IEncodeable objects.

The issue seems to be in the method readFieldInfoFromClass() of EncodeableDesc, which is called for each field when using the readFromClass() static method.

static FieldInfo readFieldInfoFromClass(Field f)
{
    f.setAccessible(true);
    Class<?> clazz          = f.getType();
    Integer builtinType     = BuiltinsMap.ID_MAP.get(clazz);
    int bt                  = builtinType == null ? -1 : builtinType;
    boolean isArray         = clazz.isArray();
    return new FieldInfo(bt, f, isArray, clazz);
}

If the field being processed is an array of complex objects (which implement IEncodeable), the class information associated to the field is wrong (it represents an array instead of the single IEncodeable).
In case of non-builtin type, the assigned class should be f.getType().getComponentType(), which returns the class representing the component type of an array.

The relevant part from the serializer is the following code

// Decode encodeable 
EncodeableDesc vi = encodeableTable.get((Class<? extends IEncodeable>) fi.type);
if (vi!=null) {
    Object value = fi.isArray ? decoder.getEncodeableArray(fi.field.getName(), vi.clazz) : getEncodeable(vi.clazz, decoder);
    fi.field.set(result, value);
    continue;
}

When the reflection serializer looks for the EncodeableDesc matching the array field, it cannot find an element in the encodeable table. This happens because the parameter of the get is the type definition of the field, i.e. the array type, not the IEncodeable type.
Moreover, it is not possible to directly add the array type to the encodeable table, without using the readFromClass() facility, because the signature of the EncodeableDesc constructor allows only Class<? extends IEncodeable> objects (an array of IEncodeable type cannot be casted, the result is a compilation error).
The solution I implemented is to manually create the FieldInfo with the correct type, but it is only a workaround.
I hope everything is clear with the issue explanation.

Thank you.

Riccardo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant