]
Thomas Diesler updated JBWS-1863:
---------------------------------
Summary: NAMESPACE_ERR on SOAPBody.addDocument(Document doc) with NS unqualified nodes
(was: NAMESPACE_ERR on invoking SOAPBodyImpl SOAPBodyElement addDocument(Document doc)
with a document composed of ElementImpl nodes.)
NAMESPACE_ERR on SOAPBody.addDocument(Document doc) with NS
unqualified nodes
-----------------------------------------------------------------------------
Key: JBWS-1863
URL:
http://jira.jboss.com/jira/browse/JBWS-1863
Project: JBoss Web Services
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: jbossws-native
Affects Versions: jbossws-1.2.1
Environment: Windows XP. Java version "1.5.0_10". JBossAS 5.0.0.2
Reporter: Eddie Waner
Assigned To: Thomas Diesler
When creating a SOAP response for a web service following the @WebServiceProvider
pattern, documents that are composed of ElementImpl nodes rather than ElementNSImpl nodes
cause Xerces to throw a NAMESPACE_ERR exception. JBoss WS assumes that nodes coming in on
the document are ElementImplNS nodes. If a document composed of ElementImpl nodes is
passed to SOAPBodyElement addDocument(Document doc) the qualified name ends up being null
in the call to Xerces ElementNSImpl setName(String namespaceURI, String qname). Thus the
name space error... See stack trace and detail below.
I ran into this problem using the Castor framework. This framework only creates
ElementImpl nodes. I also reproduced the problem with simple cases. See below.
Details:
SOAPBodyImpl
SOAPBodyElement addDocument(Document doc)
creates a soapFactory and begins the copy of elements from the document into the soapBody
with the default as deep through soapFactory.createElement(rootElement). In
SOAPFactoryImpl createElement(Element domElement, boolean deep) an assumption is made that
the element passed in is an ElementNSImpl (has a localName).
SOAPFactoryImpl
...
public SOAPElement createElement(Element domElement, boolean deep) throws SOAPException
{
if (domElement == null)
throw new IllegalArgumentException("Source node cannot be null");
if (domElement instanceof SOAPElement)
return (SOAPElement)domElement;
String localName = domElement.getLocalName();
String prefix = domElement.getPrefix() != null ? domElement.getPrefix() :
"";
String nsURI = domElement.getNamespaceURI() != null ? domElement.getNamespaceURI()
: "";
...
In the case of an ElementImpl the localName is null as well as the prefix, ElementImpl
will have the field name set. Thus when DOMUtils createElement(String localPart, String
prefix, String url) is called the localPart == null but the prefix is an empty string.
DOMUtils
...
public static Element createElement(String localPart, String prefix, String uri)
{
Document doc = getOwnerDocument();
if (prefix == null || prefix.length() == 0)
{
log.trace("createElement {" + uri + "}" + localPart);
return doc.createElementNS(uri, localPart);
}
else
{
log.trace("createElement {" + uri + "}" + prefix +
":" + localPart);
return doc.createElementNS(uri, prefix + ":" + localPart);
}
}
...
So the call into Xerces for createElementNS fails on setName(String namespaceURI, String
qname) in ElementNSImpl as noted in the comment in the Xerces code:
//NAMESPACE_ERR:
//1. if the qualified name is 'null' it is malformed.
//2. or if the qualifiedName is null and the namespaceURI is different from
null,
// We dont need to check for namespaceURI != null, if qualified name is null
throw DOMException.
ElementNSImpl.java
private void setName(String namespaceURI, String qname) {
String prefix;
// DOM Level 3: namespace URI is never empty string.
this.namespaceURI = namespaceURI;
if (namespaceURI != null) {
//convert the empty string to 'null'
this.namespaceURI = (namespaceURI.length() == 0) ? null : namespaceURI;
}
int colon1, colon2 ;
//NAMESPACE_ERR:
//1. if the qualified name is 'null' it is malformed.
//2. or if the qualifiedName is null and the namespaceURI is different from
null,
// We dont need to check for namespaceURI != null, if qualified name is null
throw DOMException.
if(qname == null){
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NAMESPACE_ERR",
null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
Stack Trace:
org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object
in a way which is incorrect with regard to namespaces.
at org.apache.xerces.dom.ElementNSImpl.setName(ElementNSImpl.java:105)
at org.apache.xerces.dom.ElementNSImpl.<init>(ElementNSImpl.java:80)
at org.apache.xerces.dom.CoreDocumentImpl.createElementNS(CoreDocumentImpl.java:2076)
at org.jboss.ws.core.utils.DOMUtils.createElement(DOMUtils.java:179)
at org.jboss.ws.core.soap.SOAPElementImpl.<init>(SOAPElementImpl.java:84)
at org.jboss.ws.core.soap.SOAPFactoryImpl.createElement(SOAPFactoryImpl.java:95)
at org.jboss.ws.core.soap.SOAPFactoryImpl.createElement(SOAPFactoryImpl.java:121)
at org.jboss.ws.core.soap.SOAPFactoryImpl.createElement(SOAPFactoryImpl.java:101)
at org.jboss.ws.core.soap.SOAPBodyImpl.addDocument(SOAPBodyImpl.java:97)
at
com.hhn.services.hl7.MessageHandler.createResponseSOAPMessage(MessageHandler.java:182)
at com.hhn.services.hl7.MessageHandler.handleMessage(MessageHandler.java:45)
at com.hhn.services.jsr181.HHNProviderTest.invoke(HHNProviderTest.java:97)
at com.hhn.services.jsr181.HHNProviderTest.invoke(HHNProviderTest.java:1)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:121)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:110)
at
org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
at
org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at
org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at
org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:193)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at
org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at
org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at
org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
at
org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:105)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at
org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at
org.jboss.ws.integration.jboss50.ServiceEndpointInvokerEJB3.invokeServiceEndpointInstance(ServiceEndpointInvokerEJB3.java:129)
at
org.jboss.ws.core.server.AbstractServiceEndpointInvoker.invoke(AbstractServiceEndpointInvoker.java:207)
at org.jboss.ws.core.server.ServiceEndpoint.processRequest(ServiceEndpoint.java:212)
at
org.jboss.ws.core.server.ServiceEndpointManager.processRequest(ServiceEndpointManager.java:448)
at
org.jboss.ws.core.server.AbstractServiceEndpointServlet.doPost(AbstractServiceEndpointServlet.java:114)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at
org.jboss.ws.core.server.AbstractServiceEndpointServlet.service(AbstractServiceEndpointServlet.java:75)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:174)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:86)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:624)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:595)
Test:
boolean createNS = false;
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
document = builder.newDocument();
if(createNS){
Element element = document.createElementNS(null, "Moo");
document.appendChild(element);
}
else
{
// Causes the NAMESPACE_ERR to be thrown
Element element = document.createElement("Moo");
element.appendChild(document.createTextNode(messageType));
}
MessageFactory messageFactory =
MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
message = messageFactory.createMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
SOAPBody body = envelope.getBody();
body.addDocument(document);
Workaround:
For Castor I can use the following to recreate the DOM tree...
...
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(source, domResult = new DOMResult(builder.newDocument()));
...
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: