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

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

Open
alku0571 opened this issue Jul 15, 2022 · 0 comments

Comments

@alku0571
Copy link

alku0571 commented Jul 15, 2022

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();

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