Search code examples
javajsonjaxbcxfjettison

Substituting java.lang.Object is bound to an anonymous type


I'm getting the error message:

com.sun.istack.SAXException2: Instance of "com.kp.schema.Value" is substituting "java.lang.Object", but "com.kp.schema.Value" is bound to an anonymous type.

I'm trying to Marshal Java objects to JSONObject using the cxf JSONProvider, I want the JSON Object as

{
    "KpJSON": 
    {
        "header": 
        {
            "cmd_resource": "commd",
            "cmd_action": "PUT",
        },

        "parameters":
        [
            {
                "name": "p1",
                "syntax": "string",
                "value": "text1"
            },
            {
                "name": "p2",
                "syntax": "integer",
                "value": 1
            },
            {
                "name": "input",
                "syntax": "container",
                "value":
                [
                    {
                        "name": "ch1",
                        "syntax": "string",
                        "value": "file"
                    },
                    {
                        "name": "ch2",
                        "syntax": "boolean",
                        "value": false
                    }
                ]
            }  
        ]
    }
}

My paramters.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "name",
    "syntax",
    "value"
})
@XmlRootElement(name = "parameters")
public class Parameters {

    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true)
    protected SyntaxType syntax;
    @XmlElement(required = true)
    protected List<Value> value;

   //getters and setters
}

Value.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
     "name",
     "syntax",
     "value"
})
@XmlRootElement(name = "value")
public class Value {

     @XmlElement(required = true)
        protected String name;
        @XmlElement(required = true)
        protected SyntaxType syntax;
        @XmlElement(required = true)
        protected List<Value> value;
       //getters and setters
}

When I tried change the List type to Value in Paramters.java and modified Value.java to following

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "content"
})
@XmlRootElement(name = "value")
public class Value {

    @XmlElementRefs({
        @XmlElementRef(name = "name", namespace = "http://kp.com/schema/", type = JAXBElement.class),
        @XmlElementRef(name = "syntax", namespace = "http://kp.com/schema/", type = JAXBElement.class),
        @XmlElementRef(name = "value", namespace = "http://kp.com/schema/", type = Value.class)
    })
    @XmlMixed
    protected List<Object> content;
 // getters and setters
}

And tried to Create a object as follows and the output is empty for the container.

Parameters parameters3 = new Parameters();

parameters3.setName("K3");
parameters3.setSyntax(SyntaxType.CONTAINER);

Value val2 = new Value();
val2.getContent().add("sdfsdfs");
QName qname= new QName("");
JAXBElement kpsyntax = new JAXBElement(qname, SyntaxType.class, SyntaxType.CONTAINER);

kpsyntax.setValue(SyntaxType.CONTAINER);

Value val3 = new Value();
val2.getContent().add(kpsyntax);
parameters3.getValue().add(val3);


response.setHeader(header);
response.getParameters().add(parameters3); 

Json output is:

 {"KpJSON":{"header":{"cmd_resource":"command","cmd_action":"PUT"},"parameters":{"name":"K3","syntax":"container","value":""}}}

Solution

  • I fixed the problem using the second approach. As @llya was asking which com.kp.schema.Value JSON Provider had the similar issue, it was going for a cyclic reference. Hence I modified the Value class as follows.

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "content"
    })
    @XmlRootElement(name = "value")
    
        public class Value {
    
            @XmlElementRefs({
                @XmlElementRef(name = "syntax", namespace = "http://kp.com/schema/", type = JAXBElement.class),
                @XmlElementRef(name = "nodeValue", namespace = "http://kp.com/schema/", type = NodeValue.class),
                @XmlElementRef(name = "name", namespace = "http://kp.com/schema/", type = JAXBElement.class)
            })
            @XmlMixed
            @XmlAnyElement(lax = true)
            protected List<Object> content;
    

    and created NodeValue Class

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "content"
    })
    @XmlRootElement(name = "value")
    public class NodeValue {
    
        @XmlElementRefs({
            @XmlElementRef(name = "syntax", namespace = "http://kp.com/schema/", type = JAXBElement.class),
            @XmlElementRef(name = "value", namespace = "http://kp.com/schema/", type = NodeValue.class),
            @XmlElementRef(name = "name", namespace = "http://kp.com/schema/", type = JAXBElement.class)
        })
        @XmlMixed
        @XmlAnyElement(lax = true)
        protected List<Object> content;
    

    And this is how I formed the response.

    Parameters parameters3 = new Parameters();
    
            parameters3.setName("K3");
            parameters3.setSyntax(SyntaxType.CONTAINER);
            Value paramvalue3 = obj.createValue();
    
            JAXBElement<String> name = obj.createName("ch1");
            JAXBElement<SyntaxType> synt = obj.createSyntax(SyntaxType.STRING);
            NodeValue ch1Value = obj.createNodeValue();
    
            ch1Value.getContent().add("KPStringChild1");    
            paramvalue3.getContent().add(name);
            paramvalue3.getContent().add(synt);
            paramvalue3.getContent().add(ch1Value);
            parameters3.getValue().add(paramvalue3);