joelittlejohn / jsonschema2pojo

Generate Java types from JSON or JSON Schema and annotate those types for data-binding with Jackson, Gson, etc
http://www.jsonschema2pojo.org
Apache License 2.0
6.24k stars 1.66k forks source link

Failed to use customRuleFactory #1613

Closed AdamPurnomo closed 6 months ago

AdamPurnomo commented 6 months ago

I am trying to write a custom rule factor where it would wrap the type into a field wrapper. This field wrapper will be used to distinguish the serialization of the following object

User user1 = new User().withName("Adam");

String user1Serialized = OBJECT_MAPPER.writeToString(user1); // -> { "name": "Adam" }

User user2 = new User().withName("Adam").withEmail(null);

String user2Serialized = OBJECT_MAPPER.writeToString(user2); // -> { "name": "Adam", "email": null }

The implementation of field wrapper is as follow

@JsonSerialize(using = FieldWrapperSerializer.class)
public class FieldWrapper<T> {
    private T value;
    private boolean explicitlySet = false;

    public FieldWrapper() {}

    public FieldWrapper(T value) {
        this.value = value;
        this.explicitlySet = true;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
        this.explicitlySet = true;
    }

    public boolean isExplicitlySet() {
        return explicitlySet;
    }
}

public class FieldWrapperSerializer extends JsonSerializer<FieldWrapper<?>> {
    @Override
    public void serialize(FieldWrapper<?> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value.isExplicitlySet()) {
            gen.writeObject(value.getValue());
        }
    }
}

I also implement why own custom type rule and rule factor

public class NullTypeRule extends TypeRule {

    public NullTypeRule(RuleFactory ruleFactory) {
        super(ruleFactory);
    }

    @Override
    public JType apply(String nodeName, JsonNode node, JsonNode parent, JClassContainer jClassContainer, Schema schema) {
        JType fieldType = super.apply(nodeName, node, parent, jClassContainer, schema);
        return fieldType.owner().ref(FieldWrapper.class).narrow(fieldType);
    }
}

public class NullRuleFactory extends RuleFactory {
    @Override
    public Rule<JClassContainer, JType> getTypeRule() {
        return new NullTypeRule(this);
    }
}

In my build.gradle

jsonSchema2Pojo {
    source = files("${sourceSets.main.output.resourcesDir}/com/myproject/schema")
    targetPackage = 'com.myproject.generated'
    customRuleFactory = 'com.myproject.NullRuleFactory'
    generateBuilders = true
    useLongIntegers = true
}

I got the following error

Caused by: java.lang.ClassNotFoundException: com.myproject.NullRuleFactory. Can I get help on this? Thank you.

unkish commented 6 months ago

Hi

java.lang.ClassNotFoundException indicates that the cause for issue is that indicated class is not accessible during jsonschema2pojo plugin execution phase.

One could:

  1. publish artifact with com.myproject.NullRuleFactory + related classes and add it to jsonschema2pojo plugin dependencies
  2. use approach similar to https://github.com/joelittlejohn/jsonschema2pojo/issues/1488#issuecomment-1443515108
  3. use some other approach