javajsonmavenjsonschemajsonschema2pojo

Maven plugin jsonschema2pojo-maven-plugin not generating pojos for all the definitions


We are using jsonschema2pojo-maven-plugin to generate the java pojos from a json schema file. The plugin is generating the pojos for the definitions that are referred from the schema but not for all the definitions.

Is there any option to make the plugin generate the pojos for all the definitions in the schmea?

Below are the pom plugin configurations and schema definitions used, here the plugin is

this is the problem, we need to have the pojos generated for these subclass definitions as well

Maven Plugin configuration:

    <plugin>
        <groupId>org.jsonschema2pojo</groupId>
        <artifactId>jsonschema2pojo-maven-plugin</artifactId>
        <executions>
            <execution>
                <id>generate-models</id>
                <configuration>
                    <targetPackage>com.xyz.abc</targetPackage>
                    <useCommonsLang3>true</useCommonsLang3>
                </configuration>
                <goals>
                    <goal>generate</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

Json Schema:

{
  "$schema":"http://json-schema.org/draft-04/schema",
  "definitions":{
    "product":{
      "type":"object",
      "properties":{
        "type":{
          "enum":[
            "THIRD_PARTY",
            "PROPRIETARY"
          ],
          "type":"string"
        },
        "price":{
          "type":"string"
        }
      },
      "additionalProperties": false
    },
    "proprietaryProduct": {
      "type": "object",
      "properties": {
        "batchName": {
          "type": "string"
        }
      },
      "extends": "#/definitions/product"
    },
    "thirdPartyProduct": {
      "type": "object",
      "properties": {
        "thirdPartyName": {
          "type": "string"
        }
      },
      "extends": "#/definitions/product"
    }
  },
  "type":"object",
  "properties":{
    "product":{
      "type":"object",
      "$ref":"#/definitions/product"
    }
  },
  "additionalProperties":false
}

Solution

  • I managed to generate unreferenced parts of the definitions by using a custom schema rule factory, in a new maven project :

    package my.package;
    
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.node.ObjectNode;
    import com.sun.codemodel.JClassContainer;
    import com.sun.codemodel.JType;
    import org.jsonschema2pojo.Schema;
    import org.jsonschema2pojo.rules.Rule;
    import org.jsonschema2pojo.rules.RuleFactory;
    import org.jsonschema2pojo.rules.SchemaRule;
    
    import java.util.Iterator;
    
    public class JsonSchemaRuleFactory extends RuleFactory {
    
        @Override
        public Rule<JClassContainer, JType> getSchemaRule() {
            return new MySchemaRule(this);
        }
    
        private class MySchemaRule extends SchemaRule {
    
            public MySchemaRule(JsonSchemaRuleFactory jsonSchemaRuleFactory) {
                super(jsonSchemaRuleFactory);
            }
    
            @Override
            public JType apply(String nodeName, JsonNode schemaNode, JsonNode parent, JClassContainer generatableType, Schema schema) {
                final JType apply = super.apply(nodeName, schemaNode, parent, generatableType, schema);
    
                final JsonNode definitions = schemaNode.get("definitions");
                if (definitions != null && definitions.isObject()) {
                    ObjectNode objectNode = (ObjectNode) definitions;
                    final Iterator<String> nodeIterator = objectNode.fieldNames();
                    while (nodeIterator.hasNext()) {
                        final String name = nodeIterator.next();
                        try {
                            final ObjectNode node = (ObjectNode) objectNode.get(name);
                            final Schema currentSchema = getSchemaStore().create(schema, "#/definitions/" + name, getGenerationConfig().getRefFragmentPathDelimiters());
                            getSchemaRule().apply(name, node, schemaNode, generatableType.getPackage(), currentSchema);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
    
                return apply;
            }
        }
    }
    

    new dedicated maven project :

    <project>
        <groupId>my.group</groupId>
        <artifactId>jsonschema-with-all-definitions</artifactId>
        <version>1.0.0</version>
        // ...
        <dependencies>
            <dependency>
                <groupId>org.jsonschema2pojo</groupId>
                <artifactId>jsonschema2pojo-core</artifactId>
                <version>1.0.2</version>
            </dependency>
        </dependencies>
    </project>
    

    Then I modified the configuration of the jsonschema2pojo-maven-plugin as seen below:

                        <plugin>
                            <groupId>org.jsonschema2pojo</groupId>
                            <artifactId>jsonschema2pojo-maven-plugin</artifactId>
                            <version>1.0.2</version>
                            <executions>
                                <execution>
                                    <id>generateClassesFromSchema</id>
                                    <phase>generate-sources</phase>
                                    <goals>
                                        <goal>generate</goal>
                                    </goals>
    
                                </execution>
                            </executions>
                            <configuration>
                                // ...                            
    <customRuleFactory>my.package.JsonSchemaRuleFactory</customRuleFactory>
                            </configuration>
    
                            <dependencies>
                                <dependency>
                                    <groupId>my.group</groupId>
                                    <artifactId>jsonschema-with-all-definitions</artifactId>
                                    <version>1.0.0</version>
                                </dependency>
                            </dependencies>
                        </plugin>
    

    As the jsonschema aren't mine and I can't edit/correct them, I used MixIns which I registered in my ObjectMapper to add some annotations that are missing from generated classes, such as @JsonTypeInfo or else.

    Hope it helps!