1

I have a set of classes with following structure

public abstract class Rule { .... }
public class RuleType1 extends Rule { ... }
public class RuleType2 extends Rule { ... }
public class RuleType3 extends Rule { ... }
public class RuleType4 extends Rule { ... }

public class RuleSet extends Rule {
     ... 
     private final Collection<Rule> rules;
}

I want to parse following json, which contains multiple nested Rule child classes. Since RuleSet contains Collection of Rule, it can have multiple RuleSet as well.

I have checked these answers already. I don't want to implement custom (de)serializer because that will make child classes less flexible. (Whoever will change classes will need to change serializer classes as well)

Deserializing an abstract class in Gson

Gson serialize a list of polymorphic objects

Here is the same json, I want to serialize/deserialize.

{
    "ruleType": "ruleSet",
    "rules": [
        {
            "ruleType": "ruleSet",
            "rules": [
                {
                    "ruleType": "RuleType1"
                },
                {
                    "ruleType": "ruleSet",
                    "rules": [
                        {
                            "ruleType": "RuleType2"
                        },
                        {
                            "ruleType": "RuleType3"
                        }
                    ]
                }
            ]
        },
        {
            "ruleType": "ruleSet",
            "rules": [
                {
                    "ruleType": "RuleType1"
                },
                {
                    "ruleType": "ruleSet",
                    "rules": [
                        {
                            "ruleType": "RuleType3"
                        },
                        {
                            "ruleType": "RuleType4"
                        }
                    ]
                }
            ]
        }
    ]
}

Edit after comments:

enter image description here This is my class structure where RuleSet has Collection<IRule> rules

And this is my class

public class SampleClass {
    public IRule parameters;
    public double defaultConfidence;
    public String ruleType;
}
    static RuntimeTypeAdapterFactory<IRule> adaptor = RuntimeTypeAdapterFactory.of(IRule.class)
            .registerSubtype(RuleSet.class)
            .registerSubtype(Rule.class);

    static RuntimeTypeAdapterFactory<Rule> ruleAdaptor = RuntimeTypeAdapterFactory.of(Rule.class)
            .registerSubtype(DocumentTypesRule.class)
            .registerSubtype(DataAttributesRule.class)
            .registerSubtype(DictionariesRule.class)
            .registerSubtype(FileFormatsRule.class)
            .registerSubtype(FileLengthRule.class)
            .registerSubtype(FileNamePatternsRule.class)
            .registerSubtype(FixedRule.class)
            .registerSubtype(ImageTypesRule.class)
            .registerSubtype(KeywordsRule.class)
            .registerSubtype(RegexesRule.class)
            .registerSubtype(SimilaritiesRule.class)
            .registerSubtype(TopicsRule.class);

    private static final Gson GSON = new GsonBuilder()
            .registerTypeAdapterFactory(adaptor)
            .registerTypeAdapterFactory(ruleAdaptor)
            .create();

and facing following error while calling GSON.fromJson(response, SampleClass.class)

java.lang.RuntimeException: Unable to invoke no-args constructor for interface <classPath>.IRule. Registering an InstanceCreator with Gson for this type may fix this problem.
Sahib Yar
  • 1,030
  • 11
  • 29
  • Please have a look at the answers to https://stackoverflow.com/q/15736654; gson-extras' `RuntimeTypeAdapterFactory` seems to fit for your use case. Unfortunately it is not published on Maven Central though. – Marcono1234 Oct 04 '22 at 19:26
  • As I have already mentioned I have already tried `RuntimeTypeAdapterFactory` and it is not working for me. – Sahib Yar Oct 05 '22 at 05:49
  • You only mentioned that you did not want to implement a custom (de)serializer; you did not mention that you already tried the `RuntimeTypeAdapterFactory` approach. Please include the code you have so far and describe why it is not working, e.g. throwing an exception, producing wrong results (if so which), ... – Marcono1234 Oct 05 '22 at 22:11

0 Answers0