简体   繁体   中英

Local part cannot be "null" when creating a QName

We are trying to track down a bug. We get the above error in the logs.

Can anyone explain what this message means? Are there any typical reasons for getting this message?

The stacktrace is:

org.apache.axiom.om.OMException: java.lang.IllegalArgumentException: local part cannot be "null" when creating a QName
            at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:206)
            at org.apache.axiom.om.impl.llom.OMNodeImpl.build(OMNodeImpl.java:318)
            at org.apache.axiom.om.impl.llom.OMElementImpl.build(OMElementImpl.java:618)
            at org.apache.axis2.jaxws.message.util.impl.SAAJConverterImpl.toOM(SAAJConverterImpl.java:147)
            at org.apache.axis2.jaxws.message.impl.XMLPartImpl._convertSE2OM(XMLPartImpl.java:77)
            at org.apache.axis2.jaxws.message.impl.XMLPartBase.getContentAsOMElement(XMLPartBase.java:203)
            at org.apache.axis2.jaxws.message.impl.XMLPartBase.getAsOMElement(XMLPartBase.java:255)
            at org.apache.axis2.jaxws.message.impl.MessageImpl.getAsOMElement(MessageImpl.java:464)
            at org.apache.axis2.jaxws.message.util.MessageUtils.putMessageOnMessageContext(MessageUtils.java:202)
            at org.apache.axis2.jaxws.core.controller.AxisInvocationController.prepareRequest(AxisInvocationController.java:370)
            at org.apache.axis2.jaxws.core.controller.InvocationController.invoke(InvocationController.java:120)
            at org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler.invokeSEIMethod(JAXWSProxyHandler.java:317)
            at org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler.invoke(JAXWSProxyHandler.java:148)

I got the same error message (local part cannot be "null" when creating a QName) while trying to construct a org.w3c.dom.Document from String. The problem went away after calling setNamespaceAware(true) on DocumentBuilderFactory. Working code snippet is given below.

private static Document getDocumentFromString(final String xmlContent)
  throws Exception
{
    DocumentBuilderFactory documentBuilderFactory =
                                DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    try
    {
        return documentBuilderFactory
                    .newDocumentBuilder()
                    .parse(new InputSource(new StringReader(xmlContent)));
    }
    catch (Exception e)
    {
        throw new RuntimeException(e);
    }
}   

It means you are creating a DOM element or attribute using one of the namespace methods like createElementNS thus

document.createElementNS(namespace, null)

or createElementNS or setAttrbuteNS and the second argument, the qname is null , or includes a prefix but no local part as in "foo:" .

EDIT:

I would try to run the XML it's parsing through a validator. It's likely there's some tag or attribute name like foo: or foo:bar:baz that is a valid XML identifier but invalid according to the additional restrictions introduced by XML namespaces.

After whole hours in searching, I just wanted to share the Answer in this thread helped me with a Talend code migration - involving SOAP messages - from java8 to java11.

// Used libraries
import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.SOAPBody;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

...

// This is the node I want to replace: "<DataArea><Contact/></DataArea>"
// <SOAP-ENV:Body> > SOAP Action (e.g. <ns:GetContact>) > <GetContactRequest> > <DataArea>
SOAPBody soapBodyRequest = objSOAPMessage.getSOAPPart().getEnvelope().getBody();
Node nodeDataArea = soapBodyRequest.getFirstChild().getFirstChild().getFirstChild(); 

// Build a valid Node object starting from a string e.g. "<Contact> etc etc nested-etc </Contact>"
DocumentBuilderFactory objDocumentBuilderFactory = DocumentBuilderFactory.newInstance();

// As per java11, this is essential. It forces the Factory to consider the ':' as a namespace separator rather than part of a tag.
objDocumentBuilderFactory.setNamespaceAware(true); 

// Create the node to replace "<DataArea><Contact/></DataArea>" with "<DataArea><Contact>content and nested tags</Contact></DataArea>"
Node nodeParsedFromString = objDocumentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(strDataArea.getBytes())).getDocumentElement();
        
// Import the newly parsed Node object in the request envelop being built and replace the existing node.
nodeDataArea.replaceChild(
        /*newChild*/nodeDataArea.getOwnerDocument().importNode(nodeParsedFromString, true), 
        /*oldChild*/nodeDataArea.getFirstChild()
);

This throws the Local part cannot be "null" when creating a QName exception if you don't put the .setNamespaceAware(true) instruction

Although this is an old thread, I hope this answer would help some one else searching this error. I have faced the same error when I was trying to build a web app using maven-enunciate-cxf-plugin:1.28.

For me this was caused after I added a checked exception to my web service signature:

    @WebMethod(operationName = "enquirySth")
    public IBANResponse enquirySth(String input) throws     I 
   InvalidInputException { ...

I have used JAX-WS Spec for exception throwing but no success. At the end I have found this issue in Enunciate issue tracker system which indicates this issue is resolved in current version, but I think it still exist.

Finally I have done following workaround to fix my problem: adding @XmlRootElement to my FaultBean.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "FaultBean",propOrder = {"errorDescription", "errorCode"})
public class FaultBean implements Serializable {
@XmlElement(required = true, nillable = true)
protected String errorDescription;
@XmlElement(required = true, nillable = true)
protected String errorCode;

public FaultBean() {
}

public String getErrorDescription() {
    return this.errorDescription;
}

public void setErrorDescription(String var1) {
    this.errorDescription = var1;
}

public String getErrorCode() {
    return this.errorCode;
}

public void setErrorCode(String var1) {
    this.errorCode = var1;
}
}

That's it. Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM