11 Replies Latest reply on Feb 25, 2008 2:38 PM by Thomas Diesler

    Raw Style webservices

    Vinicius Carvalho Apprentice

      Hello there! As I've been reporting here [and getting good support]. I'm developing a rawstyle ws using @WSProvide annotation.

      After getting things working (jboss WS 2.0.1, downgrading to jdk 5 because SAAJ version). Now things are starting to work, but I'm getting an exception:

      NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.

      Searching around I found out that some users have this issue due problems with Xalan version. All I'm trying to do is add a Document to the body of the SOAPMessage. I've been using almost the same example as the one on JEE tutorials. I'm wondering what's going wrong:

      @ServiceMode(value=Service.Mode.MESSAGE)
      public class CommandProcessor implements Provider<SOAPMessage> {
       Source returnMessage;
       public SOAPMessage invoke(SOAPMessage messge) {
       SOAPMessage returnMessage = null;
       try{
       MessageFactory mf = MessageFactory.newInstance();
       returnMessage = mf.createMessage();
       returnMessage.getSOAPBody().addDocument(createResponseContent());
       returnMessage.saveChanges();
       }catch (Exception e) {
       e.printStackTrace();
       }
      
       return returnMessage;
       }
      
       private Document createResponseContent() throws Exception{
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       dbf.setNamespaceAware(true);
       DocumentBuilder db = dbf.newDocumentBuilder();
       Document doc = db.newDocument();
       Element responseCommand = doc.createElementNS("http://www.abc.com/sys/schemas", "sys:responseCommand");
      
       Element id = doc.createElement("id");
       id.appendChild(doc.createTextNode("1"));
       Element message = doc.createElement("message");
       message.appendChild(doc.createTextNode("comando recebido"));
       responseCommand.appendChild(id);
       responseCommand.appendChild(message);
       doc.appendChild(responseCommand);
       return doc;
       }
      


      I was thinking that the problem should be related to my schema declaration, but Sun's example uses an document that does not even declare an schema its a simple xml with no schema.

      Any ideas?

      Regards

        • 1. Re: Raw Style webservices
          Richard Opalka Newbie

          Hi,

          try tu upgrade your xalan and xerces versions by applying the Java endorsed mechanism.

          Richard

          • 2. Re: Raw Style webservices
            Vinicius Carvalho Apprentice

            Thanks, I gave up on the Message style to go to Payload. this problem was solved :) Have new ones :(

            Regards

            • 3. Re: Raw Style webservices
              Oskar Carlstedt Novice

              Hmmm....

              I think I had this problem a long time ago. As I can remember it is the Document type that gives you the problem. Try adding an element instead of a document. I think the xml parser will complain about adding a document node to an existing document which is not allowed. Try adding element instead and your code shall work.

              Cheers,
              Oskar

              • 4. Re: Raw Style webservices
                Vinicius Carvalho Apprentice

                Well, that did not work as well. It also throws an exception when I try:

                MessageFactory mf = MessageFactory.newInstance();
                 returnMessage = mf.createMessage();
                 SOAPFactory f = SOAPFactory.newInstance();
                 SOAPBody body = returnMessage.getSOAPBody();
                 body.addChildElement(f.createElement(createResponseContent()));
                


                I'm really starting to think that might have a bug on the jbossws :(

                Regards

                • 5. Re: Raw Style webservices
                  Vinicius Carvalho Apprentice

                  Yeah, believe that there's a bug, the following work with no problem at all:

                  SOAPElement test = f.createElement("CommandResponse","sys","http://www.acme.com/sys/schemas");
                  returnMessage.addChildElement(test);
                  


                  • 6. Re: Raw Style webservices
                    Richard Opalka Newbie

                     

                    "viniciuscarvalho" wrote:
                    It also throws an exception when I try:


                    Could you post the stacktrace?

                    Richard

                    • 7. "
                      Vinicius Carvalho Apprentice

                      Sure :)

                      Here's the code:

                      public SOAPMessage invoke(SOAPMessage message) {
                       SOAPMessage returnMessage = null;
                       try {
                       MessageFactory mf = MessageFactory.newInstance();
                       returnMessage = mf.createMessage();
                       SOAPFactory f = SOAPFactory.newInstance();
                       SOAPElement test = f.createElement("processResponse","ns1", "http://www.acme.com/sys/schemas");
                       test.addNamespaceDeclaration("ns2","http://www.acme.com/sys/definitions");
                       test.appendChild(createResponseContent());
                       SOAPBody body = returnMessage.getSOAPBody();
                      
                       body.addChildElement(test);
                       } catch (SOAPException e) {
                       // TODO Auto-generated catch block
                       e.printStackTrace();
                       } catch (Exception e) {
                       // TODO Auto-generated catch block
                       e.printStackTrace();
                       }
                      
                       return returnMessage;
                       }
                      
                      private Element createResponseContent() throws Exception{
                       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                       dbf.setNamespaceAware(true);
                       DocumentBuilder db = dbf.newDocumentBuilder();
                       Document doc = db.newDocument();
                       Element ret = doc.createElement("return");
                       Element id = doc.createElement("id");
                       id.appendChild(doc.createTextNode("1"));
                       Element message = doc.createElement("message");
                       message.appendChild(doc.createTextNode("comando recebido"));
                       ret.appendChild(id);
                       ret.appendChild(message);
                       return ret;
                       }
                      


                      What I'd like to return is :

                      <ns1:processResponse xmlns:ns1="http://www.acme.com/sys/schemas">




                      </ns1:processResponse>

                      Here's the stack trace:

                      10:45:12,569 ERROR [STDERR] 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.
                      10:45:12,570 ERROR [STDERR] at org.apache.xerces.dom.ElementNSImpl.setName(Unknown Source)
                      10:45:12,570 ERROR [STDERR] at org.apache.xerces.dom.ElementNSImpl.<init>(Unknown Source)
                      10:45:12,570 ERROR [STDERR] at org.apache.xerces.dom.CoreDocumentImpl.createElementNS(Unknown Source)
                      10:45:12,570 ERROR [STDERR] at org.jboss.wsf.common.DOMUtils.createElement(DOMUtils.java:202)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ws.core.soap.SOAPElementImpl.<init>(SOAPElementImpl.java:84)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ws.core.soap.SOAPFactoryImpl.createElement(SOAPFactoryImpl.java:95)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ws.core.soap.SOAPFactoryImpl.createElement(SOAPFactoryImpl.java:122)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ws.core.soap.SOAPFactoryImpl.createElement(SOAPFactoryImpl.java:101)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ws.core.soap.NodeImpl.convertDOMNode(NodeImpl.java:563)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ws.core.soap.NodeImpl.appendChild(NodeImpl.java:459)
                      10:45:12,571 ERROR [STDERR] at com.acme.sys.services.provider.CommandProcessorMessage.invoke(CommandProcessorMessage.java:38)
                      10:45:12,571 ERROR [STDERR] at com.acme.sys.services.provider.CommandProcessorMessage.invoke(CommandProcessorMessage.java:1)
                      10:45:12,571 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      10:45:12,571 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                      10:45:12,571 ERROR [STDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                      10:45:12,571 ERROR [STDERR] at java.lang.reflect.Method.invoke(Method.java:585)
                      10:45:12,571 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
                      10:45:12,571 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
                      10:45:12,571 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      10:45:12,571 ERROR [STDERR] at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
                      10:45:12,571 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      10:45:12,571 ERROR [STDERR] at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
                      10:45:12,571 ERROR [STDERR] at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
                      10:45:12,571 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      10:45:12,571 ERROR [STDERR] at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
                      10:45:12,572 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      10:45:12,572 ERROR [STDERR] at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
                      10:45:12,572 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      10:45:12,572 ERROR [STDERR] at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
                      10:45:12,572 ERROR [STDERR] at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:106)
                      10:45:12,572 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      10:45:12,572 ERROR [STDERR] at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
                      10:45:12,572 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      10:45:12,572 ERROR [STDERR] at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
                      10:45:12,572 ERROR [STDERR] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      10:45:12,572 ERROR [STDERR] at org.jboss.wsf.container.jboss42.InvocationHandlerEJB3.invoke(InvocationHandlerEJB3.java:103)
                      10:45:12,572 ERROR [STDERR] at org.jboss.ws.core.server.ServiceEndpointInvoker.invoke(ServiceEndpointInvoker.java:220)
                      10:45:12,572 ERROR [STDERR] at org.jboss.wsf.stack.jbws.RequestHandlerImpl.processRequest(RequestHandlerImpl.java:408)
                      10:45:12,572 ERROR [STDERR] at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleRequest(RequestHandlerImpl.java:272)
                      10:45:12,572 ERROR [STDERR] at org.jboss.wsf.stack.jbws.RequestHandlerImpl.doPost(RequestHandlerImpl.java:189)
                      10:45:12,572 ERROR [STDERR] at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:122)
                      10:45:12,572 ERROR [STDERR] at org.jboss.wsf.stack.jbws.EndpointServlet.service(EndpointServlet.java:84)
                      10:45:12,572 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
                      10:45:12,572 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                      10:45:12,572 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                      10:45:12,572 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                      10:45:12,572 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                      10:45:12,572 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                      10:45:12,573 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
                      10:45:12,573 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
                      10:45:12,573 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
                      10:45:12,573 ERROR [STDERR] at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
                      10:45:12,573 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
                      10:45:12,573 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
                      10:45:12,573 ERROR [STDERR] at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
                      10:45:12,573 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
                      10:45:12,573 ERROR [STDERR] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
                      10:45:12,573 ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
                      10:45:12,574 ERROR [STDERR] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
                      10:45:12,574 ERROR [STDERR] at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
                      10:45:12,574 ERROR [STDERR] at java.lang.Thread.run(Thread.java:595)
                      
                      


                      Regards


                      • 8. Re: Raw Style webservices
                        Richard Opalka Newbie

                        Well,

                        this is caused by "Xerces outstanding feature" where xerces makes it impossible to merge node trees created in different document builders :-(
                        Your workaround to your problem is to use:

                        org.jboss.wsf.common.DOMUtils.getDocumentBuilder()

                        method instead of the following block of code:
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                         dbf.setNamespaceAware(true);
                         DocumentBuilder db = dbf.newDocumentBuilder();


                        This is the only way for you to use the same document builder by which your SOAP message was created.

                        Richard

                        • 9. Re: Raw Style webservices
                          Vinicius Carvalho Apprentice

                          Richard, that did not work either :( The same error was thrown. I tried:

                          DocumentBuilder db = DOMUtils.getDocumentBuilder();
                          Document doc = db.newDocument();
                          


                          and also
                          Document doc = DOMUtils.getOwnerDocument();
                          


                          Both throws the same error.

                          Regards

                          • 10. Re: Raw Style webservices
                            Eddie Waner Newbie

                            I had the same problem with the web service provider style of web service. I am using jbossas 5 beta two with jbossws 1.2.1. It appears that jboss beta two uses xerces-2.7.1. After assembling all of the sources I found the ?real? cause of the NAMESPACE_ERR exception to be of mixing DOM 1 vs DOM 2 APIs.

                            When a document is set for the SOAP body the dom tree for that document is copied into the soap body. If that document is made up of ElementImpl nodes rather than ElementNSImpl the call into Xerces fails with the now familiar NAMESPACE_ERR. To work around this issue change your code to use ?createElementNS?.

                            I happen to be using Castor, which creates documents composed of ElementImpl nodes. I have a work around using the TransformerFactory of Xalan to create a new doc tree but would rather not have to copy the document twice.

                            The 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);
                             }


                            Test Code:

                            The following snippet shows the exception.

                            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);


                            Documentation:
                            http://xerces.apache.org/xerces-j/apiDocs/org/apache/xerces/dom/ElementNSImpl.html
                            vs
                            http://xerces.apache.org/xerces-j/apiDocs/org/apache/xerces/dom/ElementImpl.html