javaxmlxsdjaxbopc-ua

JAXB Context expects empty namespace no matter what


I am facing an issue when unmarshalling an XML to my XJC Schema based generated classes using JAXB. I have read every post I've found so far, trying already who knows how many things, without success.

I have generated my Java classes using xjc -d "/myDir/src" -p nodeset.generated ./UANodeSet.xsd, where UANodeSet.xsd is this.

In my Java code, I call unmarshall the NodeSet2.xml file to the generated class UANodeSet (Root element) like:

String packageName = UANodeSet.class.getPackage().getName();
JAXBContext context = JAXBContext.newInstance(packageName);
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setEventHandler(event -> {
                System.err.println("JAXB EVENT: " + event.getMessage());
                return true; // continue after error
            });
String filePath = "C:/Users/mr/Downloads/Opc.Ua.NodeSet2.xml";
File file = new File(filePath);
JAXBElement<UANodeSet> nodeSet = (JAXBElement<UANodeSet>)unmarshaller.unmarshal(new StreamSource(file), UANodeSet.class);
UANodeSet nd = nodeSet.getValue();

This outputs the following:

JAXB EVENT: unexpected element (uri:"http://opcfoundation.org/UA/2011/03/UANodeSet.xsd", local:"Models"). Expected elements are <{}models>,<{}serverUris>,<{}extensions>,<{}aliases>,<{}namespaceUris>,<{}lastModified> 
JAXB EVENT: unexpected element (uri:"http://opcfoundation.org/UA/2011/03/UANodeSet.xsd", local:"Aliases"). Expected elements are <{}models>,<{}serverUris>,<{}extensions>,<{}aliases>,<{}namespaceUris>,<{}lastModified> 
JAXB EVENT: unexpected element (uri:"http://opcfoundation.org/UA/2011/03/UANodeSet.xsd", local:"UAObject"). Expected elements are <{}models>,<{}serverUris>,<{}extensions>,<{}aliases>,<{}namespaceUris>,<{}lastModified> 
JAXB EVENT: unexpected element (uri:"http://opcfoundation.org/UA/2011/03/UANodeSet.xsd", local:"UAObject"). Expected elements are <{}models>,<{}serverUris>,<{}extensions>,<{}aliases>,<{}namespaceUris>,<{}lastModified> 
JAXB EVENT: unexpected element (uri:"http://opcfoundation.org/UA/2011/03/UANodeSet.xsd", local:"UADataType"). Expected elements are <{}models>,<{}serverUris>,<{}extensions>,<{}aliases>,<{}namespaceUris>,<{}lastModified>

...

and nd is populated with a UANodeSet object with null values.

I confirm I have a file named package-info.java within the same package (nodeset.generated) with the following content:

@XmlSchema(
    namespace = "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd",
    elementFormDefault = XmlNsForm.QUALIFIED)
package nodeset.generated;

import jakarta.xml.bind.annotation.XmlNsForm;
import jakarta.xml.bind.annotation.XmlSchema;

To have as reference, here is what UANodeSet looks like:

package nodeset.generated;

import java.util.ArrayList;
import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElements;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlSchemaType;
import jakarta.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "namespaceUris",
    "serverUris",
    "models",
    "aliases",
    "extensions",
    "uaObjectOrUAVariableOrUAMethod"
})
@XmlRootElement(name = "UANodeSet")
public class UANodeSet {

    @XmlElement(name="NamespaceUris")
    protected UriTable namespaceUris;
    @XmlElement(name="ServerUris")
    protected UriTable serverUris;
    @XmlElement(name="Models")
    protected ModelTable models;
    @XmlElement(name="Aliases")
    protected AliasTable aliases;
    @XmlElement(name="Extensions")
    protected ListOfExtensions extensions;
    @XmlElements({
        @XmlElement(name="UAObject", type = UAObject.class),
        @XmlElement(name="UAVariable", type = UAVariable.class),
        @XmlElement(name="UAMethod", type = UAMethod.class),
        @XmlElement(name="UAView", type = UAView.class),
        @XmlElement(name="UAObjectType", type = UAObjectType.class),
        @XmlElement(name="UAVariableType", type = UAVariableType.class),
        @XmlElement(name="UADataType", type = UADataType.class),
        @XmlElement(name="UAReferenceType", type = UAReferenceType.class)
    })
    protected List<UANode> uaObjectOrUAVariableOrUAMethod;
    @XmlAttribute(name = "LastModified")
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar lastModified;

...

Things I've tried

  1. Instantiate the JAXBContext from UANodeSet.class (JAXBContext context = JAXBContext.newInstance(UANodeSet.class);) => nothing has changed
  2. Add manually namespace = "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" to @XmlTypes and/or @XmlElements @XmlRootElement => JAXBContext continues to say the expected elements are <{}models>,<{}serverUris>,<{}extensions>,<{}aliases>,<{}namespaceUris>,<{}lastModified>
  3. Removing package-info.java file completely, and add the namespace="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" attribute everywhere (@XmlTypes, @XmlElements, @XmlRootElement) => no changes.

Basically, I cannot make my JAXBContext expect the proper namespace for the UANodeSet elements.

Any help is appreciated, I have been fighting with this since too long already.


Solution

  • Well, I cannot really explain why because I lack years of experience with Java and Plug-in Development Environment, but the problem seems to be that my XML unmarshalling is in a different plug-in as my generated classes.

    If I create my JAXBContext from ObjectFactory.class in a plug-in project different from where the package nodeset.generated is defined (package that holds the XJC generated classes), then the context doesn't know about UANodeSet class. I find it strange, because nodeset.generated is being exported, and imported in the unmarshalling package.

    I have moved the unmarshalling methods to nodeset.generated and everything worked like charm.

    If someone can give the details on why this could be, I will happily edit this answer.