Skip to content

Codegen fails to generate Enum decoder if Enum has overriden toString() method #320

Open
@alku0571

Description

@alku0571

If Enum has override on toString() method then codegen fails.

Example:

Given model:

public enum AnimalType {

    ELEPHANT("elephant");

    private String typeName;

    private AnimalType(String typeName) {
        this.typeName = typeName;
    }

    @Override
    public String toString() {
        return typeName;
    }
}
public class Animal {

    private String name;
    private AnimalType type;

    //setters, getters omitted
}

Test:

@Test
public void testJsoniterExampleDeserialize() {
    //DecodingMode.DYNAMIC_MODE_AND_MATCH_FIELD_WITH_HASH fails too
    JsonIterator.setMode(DecodingMode.DYNAMIC_MODE_AND_MATCH_FIELD_STRICTLY); 

    //Please notice that JSON don't even have AnimalType specified.
    Animal animal = JsonIterator.deserialize("{'name': 'johny'}".replace('\'', '"'), Animal.class);
}

Gives exception:

com.jsoniter.spi.JsonException: failed to generate decoder for: com.jsoniter.spi.ClassInfo@582ac61f with [], exception: javassist.CannotCompileException: [source error] no such field: AnimalType$elephant
public static java.lang.Object decode_(com.jsoniter.JsonIterator iter) throws java.io.IOException { if (iter.readNull()) { return null; }
com.jsoniter.spi.Slice field = com.jsoniter.CodegenAccess.readSlice(iter);
switch (field.len()) {
case 8: 
if (
field.at(0)==101 && 
field.at(1)==108 && 
field.at(2)==101 && 
field.at(3)==112 && 
field.at(4)==104 && 
field.at(5)==97 && 
field.at(6)==110 && 
field.at(7)==116
) {
return AnimalType.elephant;
}
break;

}
throw iter.reportError("decode enum", field + " is not valid enum for AnimalType");
}

	at com.jsoniter.Codegen.gen(Codegen.java:86)
	at com.jsoniter.Codegen.getDecoder(Codegen.java:25)
	at com.jsoniter.CodegenImplNative.genReadOp(CodegenImplNative.java:213)
	at com.jsoniter.CodegenImplNative.genField(CodegenImplNative.java:191)
	at com.jsoniter.CodegenImplObjectStrict.addFieldDispatch(CodegenImplObjectStrict.java:331)
	at com.jsoniter.CodegenImplObjectStrict.addFieldDispatch(CodegenImplObjectStrict.java:344)
	at com.jsoniter.CodegenImplObjectStrict.addFieldDispatch(CodegenImplObjectStrict.java:344)
	at com.jsoniter.CodegenImplObjectStrict.addFieldDispatch(CodegenImplObjectStrict.java:344)
	at com.jsoniter.CodegenImplObjectStrict.renderTriTree(CodegenImplObjectStrict.java:304)
	at com.jsoniter.CodegenImplObjectStrict.genObjectUsingStrict(CodegenImplObjectStrict.java:93)
	at com.jsoniter.Codegen.genSource(Codegen.java:241)
	at com.jsoniter.Codegen.gen(Codegen.java:68)
	at com.jsoniter.Codegen.getDecoder(Codegen.java:25)
	at com.jsoniter.JsonIterator.read(JsonIterator.java:385)
	at com.jsoniter.JsonIterator.read(JsonIterator.java:375)
	at com.jsoniter.JsonIterator.deserialize(JsonIterator.java:441)
	at com.jsoniter.JsonIterator.deserialize(JsonIterator.java:411)

To fix this issue it's enough to slightly modify com.jsoniter.CodegenImplEnum:38

change
byte[] fromNameBytes = e.toString().getBytes();

to

byte[] fromNameBytes = ((Enum)e).name().getBytes();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions