1
votes

Unbelievable how many questions there are already about this subject. Still, none of them helps me because what I understood is that it is a common error and I believe my code is correct because it is exactly the same as the one of another project my colleague passed me.

But.. I have this error

unable to marshal type "modules.CollaborationInfo" as an element because it is missing an @XmlRootElement annotation

Given this class CollaborationInfo:

package modules;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElementRef;


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CollaborationInfo", propOrder = {
    "AgreementRef",
    "ConversationId"
})


public class CollaborationInfo {
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name="AgreementRef")

    public static class AgreementRef {
        @XmlAttribute
        private String pmode;

        public String getPmode() {
            return pmode;
        }
        public void setPmode(String pmode) {
            this.pmode = pmode;
        }
    }

    @XmlElementRef(name = "AgreementRef")
    protected AgreementRef AgreementRef = new AgreementRef();

    @XmlElement(name="ConversationId")
    protected String ConversationId;


    public String getPmode() {
        return AgreementRef.getPmode();
    }

    public void setPmode(String value) {
        this.AgreementRef.setPmode(value);
    }


    public String getConversationId() {
        return ConversationId;
    }
    public void setConversationId(String value) {
        this.ConversationId = value;
    }


}

And as main():

public static void main(String[] args) throws Exception{
    JAXBContext contextObj = JAXBContext.newInstance(CollaborationInfo.class);
    Marshaller marshallerObj = contextObj.createMarshaller();
    marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    CollaborationInfo CI = new CollaborationInfo();
    CI.setPmode("String1");
    CI.setConversationId("String2");

    marshallerObj.marshal(CI, new FileOutputStream("C:\\OUT.xml"));
}

I should be able to have as output (OUT.xml):

<?xml version="1.0" encoding="UTF-8"?>
    <CollaborationInfo>
        <AgreementRef pmode="String1"/>
        <ConversationId>String2</ConversationId>
    </CollaborationInfo>

But I just can't. Can someone tell me where I am wrong?

(Of course the real XML is much more long and complex, but probably if I'm able to have this part working I'm able to continue the rest)

2

2 Answers

2
votes

As the errors says, you need to add the annotation @XmlRootElement in front of the class CollaborationInfo. Your @XmlRootElement is for the static class AgreementRef.

package modules;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElementRef;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CollaborationInfo", propOrder = {
    "AgreementRef",
    "ConversationId"
})
public class CollaborationInfo {

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class AgreementRef {
        @XmlAttribute
        private String pmode;

        public String getPmode() {
            return pmode;
        }
        public void setPmode(String pmode) {
            this.pmode = pmode;
        }
    }

    @XmlElement(name = "AgreementRef")
    protected AgreementRef AgreementRef = new AgreementRef();

    @XmlElement(name="ConversationId")
    protected String ConversationId;


    public String getPmode() {
        return AgreementRef.getPmode();
    }

    public void setPmode(String value) {
        this.AgreementRef.setPmode(value);
    }


    public String getConversationId() {
        return ConversationId;
    }
    public void setConversationId(String value) {
        this.ConversationId = value;
    }
}
0
votes

This is old but just in case someone runs into it, it was answered here: https://stackoverflow.com/a/59249216/5835746

Basically, you should not use the auto-generated classes directly but use the methods from ObjectFactory, which was also auto-generated by the plugin, to create instances of those classes.

Editing the auto-generated classes, to add the @XmlRootElement annotation is probably not a good idea.