schema-gen icon indicating copy to clipboard operation
schema-gen copied to clipboard

Cannot get property 'imports' on null object

Open realdadfish opened this issue 5 years ago • 3 comments

I'm trying to generate Kotlin classes for my XSDs. This is the calling code:

class CodeGen extends KotlinGen {
    CodeGen(File schemaFile, File targetDir, String targetPackage) {
        super()
        schemaURL = schemaFile.toURI().toURL()
        srcDir = targetDir
        packageName = targetPackage
        addSuffixToEnumClass = null
        anyPropertyName = 'text'
    }
}

The XSD file is valid (and was used to create Java Beans via xjc before), the targetDir is valid as well and exists, the package name is non-empty. When I execute this code in my custom task, I receive the following crash:

java.lang.NullPointerException: Cannot get property 'imports' on null object
        at com.javagen.schema.model.MSource$Imports.leftShift(MSource.groovy:83)
        at com.javagen.schema.model.MSource$Imports$leftShift.call(Unknown Source)
        at com.javagen.schema.kotlin.KotlinJacksonCallback$_gen_closure1.doCall(KotlinJacksonCallback.groovy:116)              at com.javagen.schema.kotlin.KotlinJacksonCallback.gen(KotlinJacksonCallback.groovy:113)
        at com.javagen.schema.kotlin.KotlinJacksonCallback$gen.call(Unknown Source)
        at com.javagen.schema.java.JavaGen.visit(JavaGen.groovy:357)
        at com.javagen.schema.xml.XmlSchemaVisitor$visit$2.call(Unknown Source)
        at com.javagen.schema.xml.XmlSchemaVisitor$Trait$Helper.visit(XmlSchemaVisitor.groovy:37)
        at com.javagen.schema.xml.XmlSchemaVisitor$Trait$Helper$visit$1.call(Unknown Source)
        at com.javagen.schema.java.JavaGen.visit(JavaGen.groovy:143)
        at com.javagen.schema.java.JavaGen$visit.callCurrent(Unknown Source)
        at com.javagen.schema.kotlin.KotlinGen.gen(KotlinGen.groovy:186)
        at com.javagen.schema.kotlin.KotlinGen$gen.call(Unknown Source)

My Groovy-foo is not good enough to figure out whats going on here, so maybe you have an idea?

realdadfish avatar Jan 21 '20 16:01 realdadfish

If I use JavaGen instead of KotlinGen as base class, the error is almost identical:

java.lang.NullPointerException: Cannot get property 'imports' on null object
        at com.javagen.schema.model.MSource$Imports.leftShift(MSource.groovy:83)
        at com.javagen.schema.model.MSource$Imports$leftShift.call(Unknown Source)
        at com.javagen.schema.java.JavaJacksonCallback$_gen_closure1.doCall(JavaJacksonCallback.groovy:108)
        at com.javagen.schema.java.JavaJacksonCallback.gen(JavaJacksonCallback.groovy:105)
        at com.javagen.schema.java.JavaJacksonCallback$gen.call(Unknown Source)
        at com.javagen.schema.java.JavaGen.visit(JavaGen.groovy:357)
        at com.javagen.schema.xml.XmlSchemaVisitor$visit$2.call(Unknown Source)
        at com.javagen.schema.xml.XmlSchemaVisitor$Trait$Helper.visit(XmlSchemaVisitor.groovy:37)
        at com.javagen.schema.xml.XmlSchemaVisitor$Trait$Helper$visit$1.call(Unknown Source)
        at com.javagen.schema.java.JavaGen.visit(JavaGen.groovy:143)
        at com.javagen.schema.java.JavaGen$visit.callCurrent(Unknown Source)
        at com.javagen.schema.java.JavaGen.gen(JavaGen.groovy:126)
        at com.javagen.schema.java.JavaGen$gen$3.call(Unknown Source)

realdadfish avatar Jan 21 '20 16:01 realdadfish

I debugged to it and figured that it processes an enum type and then fails to get it's parent class (the left-shift operator on enumClass.imports internally accesses enumClass.parent and that is null):

screenshot

This is the XSD snippet it stumbles across:

    <xs:simpleType name="boolean">
        <xs:restriction base="xs:string">
            <xs:enumeration value="True" />
            <xs:enumeration value="False" />
        </xs:restriction>
    </xs:simpleType>

xjc creates the following Java POJO for this:

@XmlType(name = "boolean")
@XmlEnum
public enum Boolean {

    @XmlEnumValue("True")
    TRUE("True"),
    @XmlEnumValue("False")
    FALSE("False");
    private final String value;

    Boolean(String v) {
        value = v;
    }

    public String value() {
        return value;
    }

    public static Boolean fromValue(String v) {
        for (Boolean c: Boolean.values()) {
            if (c.value.equals(v)) {
                return c;
            }
        }
        throw new IllegalArgumentException(v);
    }

}

I'm not exactly sure what this "parent" is supposed to mean in this context. XSD-wise, this type (and others) are common types that reside in a separate CommonTypes.xsd and that are imported into the specific business XSD right after the xsd:schema root element (before the first xsd:element).

realdadfish avatar Jan 21 '20 19:01 realdadfish

I wrote some code to flatten the import statement and include all the imported element definitions in the source file. Still, the code exits for the Boolean type just as before. I found another issue while testing a different XSD file, I'll open up a separate ticket for that.

realdadfish avatar Jan 27 '20 17:01 realdadfish