You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rampart-dev@ws.apache.org by Frode Ruud Laukus <la...@gmail.com> on 2009/01/07 16:18:02 UTC

Rampart blocking SOAPFaults - Error in extracting message properties

I'm having a problem with an Axis2 webservice secured with Rampart.
The service works if Rampart is disengaged, but when engaging Rampart,
It no longer returns SOAPFaults to the caller. The caller gets an
empty HTTP 500 response only.

I'm not if this is a bug in Rampart, or something peculiar with my
environment.. or simply me not understanding how Rampart or
AXIOM/Axis2 works.

The error message initially was:

org.apache.axis2.AxisFault: Error in extracting message properties

Stacktrace:
org.apache.rampart.handler.RampartSender.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(RampartSender.java:90)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.rampart.handler.RampartSender.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(RampartSender.java:90)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.engine.Phase.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(Phase.java:317)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.engine.Phase.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(Phase.java:317)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.engine.AxisEngine.invoke(Lorg/apache/axis2/context/MessageContext;Z)Lorg/apache/axis2/engine/Handler$InvocationResponse;(AxisEngine.java:273)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.engine.AxisEngine.invoke(Lorg/apache/axis2/context/MessageContext;Z)Lorg/apache/axis2/engine/Handler$InvocationResponse;(AxisEngine.java:273)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.engine.AxisEngine.sendFault(Lorg/apache/axis2/context/MessageContext;)V(AxisEngine.java:546)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.engine.AxisEngine.sendFault(Lorg/apache/axis2/context/MessageContext;)V(AxisEngine.java:546)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.transport.http.AxisServlet.handleFault(Lorg/apache/axis2/context/MessageContext;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:447)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.transport.http.AxisServlet.handleFault(Lorg/apache/axis2/context/MessageContext;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:447)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.transport.http.AxisServlet.processAxisFault(Lorg/apache/axis2/context/MessageContext;Ljavax/servlet/http/HttpServletResponse;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:392)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.transport.http.AxisServlet.processAxisFault(Lorg/apache/axis2/context/MessageContext;Ljavax/servlet/http/HttpServletResponse;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:392)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.transport.http.AxisServlet.doPost(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(AxisServlet.java:167)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
org.apache.axis2.transport.http.AxisServlet.doPost(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(AxisServlet.java:167)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
javax.servlet.http.HttpServlet.service(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(HttpServlet.java:760)
(ExecuteThread: '24' for queue:
'weblogic.kernel.Default',AxisServlet.java:402)
.
.
.


I have been digging through and debugging the source code for a while,
and I've managed drill down to an exception thrown in the Axis2Util
class in the org.apache.rampart.util package, in rampart-core-1.4.jar.
The AxisFault caught in the RampartSender.invoke method above wraps an
exception, which wraps another exception.. and so on, until I drilled
down to this class and this method.

I do however fail to understand exactly why it fails, even though I
also have managed to add a couple of lines of code that make the
problem go away. I have a hunch it has something to do with the way
AXIOM works, but I don't know.


The code in question is the getDocumentFromSOAPEnvelope method
(Rampart 1.4). I've added my own comments explaining my findings so
far in the code below (///// comments):

	/**
	 * Creates a DOM Document using the SOAP Envelope.
	 * @param env An org.apache.axiom.soap.SOAPEnvelope instance
	 * @return Returns the DOM Document of the given SOAP Envelope.
	 * @throws Exception
	 */
	public static Document getDocumentFromSOAPEnvelope(SOAPEnvelope env,
boolean useDoom)
			throws WSSecurityException {
		try {
            if(env instanceof Element) {
                return ((Element)env).getOwnerDocument();
            }

            if (useDoom) {
                env.build();

                // Workaround to prevent a bug in AXIOM where
                // there can be an incomplete OMElement as the first child body
                OMElement firstElement = env.getBody().getFirstElement();
                if (firstElement != null) {
                    firstElement.build();
                }

                //Get processed headers
                SOAPHeader soapHeader = env.getHeader();
                ArrayList processedHeaderQNames = new ArrayList();

                if(soapHeader != null) {
                    Iterator headerBlocs = soapHeader.getChildElements();
                    while (headerBlocs.hasNext()) {
                        SOAPHeaderBlock element = (SOAPHeaderBlock)
headerBlocs.next();
                        if(element.isProcessed()) {
                            processedHeaderQNames.add(element.getQName());
                        }
                    }

                }

                // Check the namespace and find SOAP version and factory
                String nsURI = null;
                SOAPFactory factory;


                if (env.getNamespace().getNamespaceURI().equals(
                        SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
                    nsURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
                    factory = DOOMAbstractFactory.getSOAP11Factory();
                } else {
                    nsURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
                    factory = DOOMAbstractFactory.getSOAP12Factory();
                }


		///// I add my own hack here or earlier to make the problem go away.
See below.


                StAXSOAPModelBuilder stAXSOAPModelBuilder = new
StAXSOAPModelBuilder(env.getXMLStreamReader(), factory, nsURI);
                SOAPEnvelope envelope = stAXSOAPModelBuilder.getSOAPEnvelope();


                /////Adding a toString on the newly built SOAPEnvelope
object fails with: "Can not serialize OM Element Envelope"
                /////System.out.println("envelope: " + envelope.toString());


		/////This line throws the initial exception
                ((OMNode) envelope.getParent()).build();



                //Set the processed flag of the processed headers
                SOAPHeader header = envelope.getHeader();
                for (Iterator iter = processedHeaderQNames.iterator(); iter
                        .hasNext();) {
                    QName name = (QName) iter.next();
                    Iterator omKids = header.getChildrenWithName(name);
                    if(omKids.hasNext()) {
                        ((SOAPHeaderBlock)omKids.next()).setProcessed();
                    }
                }

                Element envElem = (Element) envelope;
                return envElem.getOwnerDocument();
            } else {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                env.build();
                env.serialize(baos);
                ByteArrayInputStream bais = new ByteArrayInputStream(baos
                        .toByteArray());
                DocumentBuilderFactory factory = DocumentBuilderFactory
                        .newInstance();
                factory.setNamespaceAware(true);
                return factory.newDocumentBuilder().parse(bais);
            }
		} catch (Exception e) {	
			throw new WSSecurityException(
					"Error in converting SOAP Envelope to Document", e);
		}
	}


Finally, this piece of code added before the StAXSOAPModelBuilder is
in use makes the problem go away. Why?

               		StringReader rd = new StringReader(env.toString());
    			XMLStreamReader parser =
XMLInputFactory.newInstance().createXMLStreamReader(rd);
    			StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(parser, null);
    			SOAPEnvelope env2 = (SOAPEnvelope) builder.getDocumentElement();
    			env = env2;


Any insights would be appreciated!

Best Regards,
Frode Laukus

Re: Rampart blocking SOAPFaults - Error in extracting message properties

Posted by Frode Ruud Laukus <la...@gmail.com>.
I am indeed using SOAP 1.1.
I tried using the AXIOM trunk, and I'm happy to say it works fine when
replacing the axiom jar-files in the Axis2-1.4.1 distribution with the
ones built from the trunk.

Thanks a bunch, really helped me :)

Regards,
Frode Laukus


On Wed, Jan 7, 2009 at 5:53 PM, Nandana Mihindukulasooriya
<na...@gmail.com> wrote:
> Hi Frode,
>     Are you using SOAP 1.1 ? There was a issue [1], [2] in SOAP 1.1 faults
> in AXIOM DOOM implementation and it was fixed in the trunk. Can you try
> using the trunk or just patching the axiom with the patch for that issue ?
>
> thanks,
> nandana
>
> [1] - http://issues.apache.org/jira/browse/RAMPART-164
> [2] - http://issues.apache.org/jira/browse/WSCOMMONS-343
>
> On Wed, Jan 7, 2009 at 8:48 PM, Frode Ruud Laukus <la...@gmail.com> wrote:
>
>> I'm having a problem with an Axis2 webservice secured with Rampart.
>> The service works if Rampart is disengaged, but when engaging Rampart,
>> It no longer returns SOAPFaults to the caller. The caller gets an
>> empty HTTP 500 response only.
>>
>> I'm not if this is a bug in Rampart, or something peculiar with my
>> environment.. or simply me not understanding how Rampart or
>> AXIOM/Axis2 works.
>>
>> The error message initially was:
>>
>> org.apache.axis2.AxisFault: Error in extracting message properties
>>
>> Stacktrace:
>>
>> org.apache.rampart.handler.RampartSender.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(RampartSender.java:90)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.rampart.handler.RampartSender.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(RampartSender.java:90)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.engine.Phase.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(Phase.java:317)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.engine.Phase.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(Phase.java:317)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.engine.AxisEngine.invoke(Lorg/apache/axis2/context/MessageContext;Z)Lorg/apache/axis2/engine/Handler$InvocationResponse;(AxisEngine.java:273)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.engine.AxisEngine.invoke(Lorg/apache/axis2/context/MessageContext;Z)Lorg/apache/axis2/engine/Handler$InvocationResponse;(AxisEngine.java:273)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.engine.AxisEngine.sendFault(Lorg/apache/axis2/context/MessageContext;)V(AxisEngine.java:546)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.engine.AxisEngine.sendFault(Lorg/apache/axis2/context/MessageContext;)V(AxisEngine.java:546)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.transport.http.AxisServlet.handleFault(Lorg/apache/axis2/context/MessageContext;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:447)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.transport.http.AxisServlet.handleFault(Lorg/apache/axis2/context/MessageContext;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:447)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.transport.http.AxisServlet.processAxisFault(Lorg/apache/axis2/context/MessageContext;Ljavax/servlet/http/HttpServletResponse;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:392)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.transport.http.AxisServlet.processAxisFault(Lorg/apache/axis2/context/MessageContext;Ljavax/servlet/http/HttpServletResponse;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:392)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.transport.http.AxisServlet.doPost(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(AxisServlet.java:167)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> org.apache.axis2.transport.http.AxisServlet.doPost(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(AxisServlet.java:167)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>>
>> javax.servlet.http.HttpServlet.service(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(HttpServlet.java:760)
>> (ExecuteThread: '24' for queue:
>> 'weblogic.kernel.Default',AxisServlet.java:402)
>> .
>> .
>> .
>>
>>
>> I have been digging through and debugging the source code for a while,
>> and I've managed drill down to an exception thrown in the Axis2Util
>> class in the org.apache.rampart.util package, in rampart-core-1.4.jar.
>> The AxisFault caught in the RampartSender.invoke method above wraps an
>> exception, which wraps another exception.. and so on, until I drilled
>> down to this class and this method.
>>
>> I do however fail to understand exactly why it fails, even though I
>> also have managed to add a couple of lines of code that make the
>> problem go away. I have a hunch it has something to do with the way
>> AXIOM works, but I don't know.
>>
>>
>> The code in question is the getDocumentFromSOAPEnvelope method
>> (Rampart 1.4). I've added my own comments explaining my findings so
>> far in the code below (///// comments):
>>
>>        /**
>>         * Creates a DOM Document using the SOAP Envelope.
>>         * @param env An org.apache.axiom.soap.SOAPEnvelope instance
>>         * @return Returns the DOM Document of the given SOAP Envelope.
>>         * @throws Exception
>>         */
>>        public static Document getDocumentFromSOAPEnvelope(SOAPEnvelope env,
>> boolean useDoom)
>>                        throws WSSecurityException {
>>                try {
>>            if(env instanceof Element) {
>>                return ((Element)env).getOwnerDocument();
>>            }
>>
>>            if (useDoom) {
>>                env.build();
>>
>>                // Workaround to prevent a bug in AXIOM where
>>                // there can be an incomplete OMElement as the first child
>> body
>>                OMElement firstElement = env.getBody().getFirstElement();
>>                if (firstElement != null) {
>>                    firstElement.build();
>>                }
>>
>>                //Get processed headers
>>                SOAPHeader soapHeader = env.getHeader();
>>                ArrayList processedHeaderQNames = new ArrayList();
>>
>>                if(soapHeader != null) {
>>                    Iterator headerBlocs = soapHeader.getChildElements();
>>                    while (headerBlocs.hasNext()) {
>>                        SOAPHeaderBlock element = (SOAPHeaderBlock)
>> headerBlocs.next();
>>                        if(element.isProcessed()) {
>>                            processedHeaderQNames.add(element.getQName());
>>                        }
>>                    }
>>
>>                }
>>
>>                // Check the namespace and find SOAP version and factory
>>                String nsURI = null;
>>                SOAPFactory factory;
>>
>>
>>                if (env.getNamespace().getNamespaceURI().equals(
>>                        SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
>>                    nsURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
>>                    factory = DOOMAbstractFactory.getSOAP11Factory();
>>                } else {
>>                    nsURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
>>                    factory = DOOMAbstractFactory.getSOAP12Factory();
>>                }
>>
>>
>>                ///// I add my own hack here or earlier to make the problem
>> go away.
>> See below.
>>
>>
>>                StAXSOAPModelBuilder stAXSOAPModelBuilder = new
>> StAXSOAPModelBuilder(env.getXMLStreamReader(), factory, nsURI);
>>                SOAPEnvelope envelope =
>> stAXSOAPModelBuilder.getSOAPEnvelope();
>>
>>
>>                /////Adding a toString on the newly built SOAPEnvelope
>> object fails with: "Can not serialize OM Element Envelope"
>>                /////System.out.println("envelope: " + envelope.toString());
>>
>>
>>                /////This line throws the initial exception
>>                ((OMNode) envelope.getParent()).build();
>>
>>
>>
>>                //Set the processed flag of the processed headers
>>                SOAPHeader header = envelope.getHeader();
>>                for (Iterator iter = processedHeaderQNames.iterator(); iter
>>                        .hasNext();) {
>>                    QName name = (QName) iter.next();
>>                    Iterator omKids = header.getChildrenWithName(name);
>>                    if(omKids.hasNext()) {
>>                        ((SOAPHeaderBlock)omKids.next()).setProcessed();
>>                    }
>>                }
>>
>>                Element envElem = (Element) envelope;
>>                return envElem.getOwnerDocument();
>>            } else {
>>                ByteArrayOutputStream baos = new ByteArrayOutputStream();
>>                env.build();
>>                env.serialize(baos);
>>                ByteArrayInputStream bais = new ByteArrayInputStream(baos
>>                        .toByteArray());
>>                DocumentBuilderFactory factory = DocumentBuilderFactory
>>                        .newInstance();
>>                factory.setNamespaceAware(true);
>>                return factory.newDocumentBuilder().parse(bais);
>>            }
>>                } catch (Exception e) {
>>                        throw new WSSecurityException(
>>                                        "Error in converting SOAP Envelope
>> to Document", e);
>>                }
>>        }
>>
>>
>> Finally, this piece of code added before the StAXSOAPModelBuilder is
>> in use makes the problem go away. Why?
>>
>>                        StringReader rd = new StringReader(env.toString());
>>                        XMLStreamReader parser =
>> XMLInputFactory.newInstance().createXMLStreamReader(rd);
>>                        StAXSOAPModelBuilder builder = new
>> StAXSOAPModelBuilder(parser, null);
>>                        SOAPEnvelope env2 = (SOAPEnvelope)
>> builder.getDocumentElement();
>>                        env = env2;
>>
>>
>> Any insights would be appreciated!
>>
>> Best Regards,
>> Frode Laukus
>>
>
>
>
> --
> Nandana Mihindukulasooriya
> WSO2 inc.
>
> http://nandana83.blogspot.com/
> http://www.wso2.org
>

Re: Rampart blocking SOAPFaults - Error in extracting message properties

Posted by Nandana Mihindukulasooriya <na...@gmail.com>.
Hi Frode,
     Are you using SOAP 1.1 ? There was a issue [1], [2] in SOAP 1.1 faults
in AXIOM DOOM implementation and it was fixed in the trunk. Can you try
using the trunk or just patching the axiom with the patch for that issue ?

thanks,
nandana

[1] - http://issues.apache.org/jira/browse/RAMPART-164
[2] - http://issues.apache.org/jira/browse/WSCOMMONS-343

On Wed, Jan 7, 2009 at 8:48 PM, Frode Ruud Laukus <la...@gmail.com> wrote:

> I'm having a problem with an Axis2 webservice secured with Rampart.
> The service works if Rampart is disengaged, but when engaging Rampart,
> It no longer returns SOAPFaults to the caller. The caller gets an
> empty HTTP 500 response only.
>
> I'm not if this is a bug in Rampart, or something peculiar with my
> environment.. or simply me not understanding how Rampart or
> AXIOM/Axis2 works.
>
> The error message initially was:
>
> org.apache.axis2.AxisFault: Error in extracting message properties
>
> Stacktrace:
>
> org.apache.rampart.handler.RampartSender.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(RampartSender.java:90)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.rampart.handler.RampartSender.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(RampartSender.java:90)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.engine.Phase.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(Phase.java:317)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.engine.Phase.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(Phase.java:317)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.engine.AxisEngine.invoke(Lorg/apache/axis2/context/MessageContext;Z)Lorg/apache/axis2/engine/Handler$InvocationResponse;(AxisEngine.java:273)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.engine.AxisEngine.invoke(Lorg/apache/axis2/context/MessageContext;Z)Lorg/apache/axis2/engine/Handler$InvocationResponse;(AxisEngine.java:273)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.engine.AxisEngine.sendFault(Lorg/apache/axis2/context/MessageContext;)V(AxisEngine.java:546)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.engine.AxisEngine.sendFault(Lorg/apache/axis2/context/MessageContext;)V(AxisEngine.java:546)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.transport.http.AxisServlet.handleFault(Lorg/apache/axis2/context/MessageContext;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:447)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.transport.http.AxisServlet.handleFault(Lorg/apache/axis2/context/MessageContext;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:447)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.transport.http.AxisServlet.processAxisFault(Lorg/apache/axis2/context/MessageContext;Ljavax/servlet/http/HttpServletResponse;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:392)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.transport.http.AxisServlet.processAxisFault(Lorg/apache/axis2/context/MessageContext;Ljavax/servlet/http/HttpServletResponse;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:392)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.transport.http.AxisServlet.doPost(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(AxisServlet.java:167)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> org.apache.axis2.transport.http.AxisServlet.doPost(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(AxisServlet.java:167)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
>
> javax.servlet.http.HttpServlet.service(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(HttpServlet.java:760)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> .
> .
> .
>
>
> I have been digging through and debugging the source code for a while,
> and I've managed drill down to an exception thrown in the Axis2Util
> class in the org.apache.rampart.util package, in rampart-core-1.4.jar.
> The AxisFault caught in the RampartSender.invoke method above wraps an
> exception, which wraps another exception.. and so on, until I drilled
> down to this class and this method.
>
> I do however fail to understand exactly why it fails, even though I
> also have managed to add a couple of lines of code that make the
> problem go away. I have a hunch it has something to do with the way
> AXIOM works, but I don't know.
>
>
> The code in question is the getDocumentFromSOAPEnvelope method
> (Rampart 1.4). I've added my own comments explaining my findings so
> far in the code below (///// comments):
>
>        /**
>         * Creates a DOM Document using the SOAP Envelope.
>         * @param env An org.apache.axiom.soap.SOAPEnvelope instance
>         * @return Returns the DOM Document of the given SOAP Envelope.
>         * @throws Exception
>         */
>        public static Document getDocumentFromSOAPEnvelope(SOAPEnvelope env,
> boolean useDoom)
>                        throws WSSecurityException {
>                try {
>            if(env instanceof Element) {
>                return ((Element)env).getOwnerDocument();
>            }
>
>            if (useDoom) {
>                env.build();
>
>                // Workaround to prevent a bug in AXIOM where
>                // there can be an incomplete OMElement as the first child
> body
>                OMElement firstElement = env.getBody().getFirstElement();
>                if (firstElement != null) {
>                    firstElement.build();
>                }
>
>                //Get processed headers
>                SOAPHeader soapHeader = env.getHeader();
>                ArrayList processedHeaderQNames = new ArrayList();
>
>                if(soapHeader != null) {
>                    Iterator headerBlocs = soapHeader.getChildElements();
>                    while (headerBlocs.hasNext()) {
>                        SOAPHeaderBlock element = (SOAPHeaderBlock)
> headerBlocs.next();
>                        if(element.isProcessed()) {
>                            processedHeaderQNames.add(element.getQName());
>                        }
>                    }
>
>                }
>
>                // Check the namespace and find SOAP version and factory
>                String nsURI = null;
>                SOAPFactory factory;
>
>
>                if (env.getNamespace().getNamespaceURI().equals(
>                        SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
>                    nsURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
>                    factory = DOOMAbstractFactory.getSOAP11Factory();
>                } else {
>                    nsURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
>                    factory = DOOMAbstractFactory.getSOAP12Factory();
>                }
>
>
>                ///// I add my own hack here or earlier to make the problem
> go away.
> See below.
>
>
>                StAXSOAPModelBuilder stAXSOAPModelBuilder = new
> StAXSOAPModelBuilder(env.getXMLStreamReader(), factory, nsURI);
>                SOAPEnvelope envelope =
> stAXSOAPModelBuilder.getSOAPEnvelope();
>
>
>                /////Adding a toString on the newly built SOAPEnvelope
> object fails with: "Can not serialize OM Element Envelope"
>                /////System.out.println("envelope: " + envelope.toString());
>
>
>                /////This line throws the initial exception
>                ((OMNode) envelope.getParent()).build();
>
>
>
>                //Set the processed flag of the processed headers
>                SOAPHeader header = envelope.getHeader();
>                for (Iterator iter = processedHeaderQNames.iterator(); iter
>                        .hasNext();) {
>                    QName name = (QName) iter.next();
>                    Iterator omKids = header.getChildrenWithName(name);
>                    if(omKids.hasNext()) {
>                        ((SOAPHeaderBlock)omKids.next()).setProcessed();
>                    }
>                }
>
>                Element envElem = (Element) envelope;
>                return envElem.getOwnerDocument();
>            } else {
>                ByteArrayOutputStream baos = new ByteArrayOutputStream();
>                env.build();
>                env.serialize(baos);
>                ByteArrayInputStream bais = new ByteArrayInputStream(baos
>                        .toByteArray());
>                DocumentBuilderFactory factory = DocumentBuilderFactory
>                        .newInstance();
>                factory.setNamespaceAware(true);
>                return factory.newDocumentBuilder().parse(bais);
>            }
>                } catch (Exception e) {
>                        throw new WSSecurityException(
>                                        "Error in converting SOAP Envelope
> to Document", e);
>                }
>        }
>
>
> Finally, this piece of code added before the StAXSOAPModelBuilder is
> in use makes the problem go away. Why?
>
>                        StringReader rd = new StringReader(env.toString());
>                        XMLStreamReader parser =
> XMLInputFactory.newInstance().createXMLStreamReader(rd);
>                        StAXSOAPModelBuilder builder = new
> StAXSOAPModelBuilder(parser, null);
>                        SOAPEnvelope env2 = (SOAPEnvelope)
> builder.getDocumentElement();
>                        env = env2;
>
>
> Any insights would be appreciated!
>
> Best Regards,
> Frode Laukus
>



-- 
Nandana Mihindukulasooriya
WSO2 inc.

http://nandana83.blogspot.com/
http://www.wso2.org

Re: Rampart blocking SOAPFaults - Error in extracting message properties

Posted by Andreas Veithen <an...@gmail.com>.
Can you post the initial exception that is thrown by ((OMNode)
envelope.getParent()).build() ?

Andreas

On Wed, Jan 7, 2009 at 16:18, Frode Ruud Laukus <la...@gmail.com> wrote:
> I'm having a problem with an Axis2 webservice secured with Rampart.
> The service works if Rampart is disengaged, but when engaging Rampart,
> It no longer returns SOAPFaults to the caller. The caller gets an
> empty HTTP 500 response only.
>
> I'm not if this is a bug in Rampart, or something peculiar with my
> environment.. or simply me not understanding how Rampart or
> AXIOM/Axis2 works.
>
> The error message initially was:
>
> org.apache.axis2.AxisFault: Error in extracting message properties
>
> Stacktrace:
> org.apache.rampart.handler.RampartSender.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(RampartSender.java:90)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.rampart.handler.RampartSender.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(RampartSender.java:90)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.engine.Phase.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(Phase.java:317)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.engine.Phase.invoke(Lorg/apache/axis2/context/MessageContext;)Lorg/apache/axis2/engine/Handler$InvocationResponse;(Phase.java:317)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.engine.AxisEngine.invoke(Lorg/apache/axis2/context/MessageContext;Z)Lorg/apache/axis2/engine/Handler$InvocationResponse;(AxisEngine.java:273)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.engine.AxisEngine.invoke(Lorg/apache/axis2/context/MessageContext;Z)Lorg/apache/axis2/engine/Handler$InvocationResponse;(AxisEngine.java:273)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.engine.AxisEngine.sendFault(Lorg/apache/axis2/context/MessageContext;)V(AxisEngine.java:546)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.engine.AxisEngine.sendFault(Lorg/apache/axis2/context/MessageContext;)V(AxisEngine.java:546)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.transport.http.AxisServlet.handleFault(Lorg/apache/axis2/context/MessageContext;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:447)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.transport.http.AxisServlet.handleFault(Lorg/apache/axis2/context/MessageContext;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:447)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.transport.http.AxisServlet.processAxisFault(Lorg/apache/axis2/context/MessageContext;Ljavax/servlet/http/HttpServletResponse;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:392)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.transport.http.AxisServlet.processAxisFault(Lorg/apache/axis2/context/MessageContext;Ljavax/servlet/http/HttpServletResponse;Ljava/io/OutputStream;Lorg/apache/axis2/AxisFault;)V(AxisServlet.java:392)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.transport.http.AxisServlet.doPost(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(AxisServlet.java:167)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> org.apache.axis2.transport.http.AxisServlet.doPost(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(AxisServlet.java:167)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> javax.servlet.http.HttpServlet.service(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V(HttpServlet.java:760)
> (ExecuteThread: '24' for queue:
> 'weblogic.kernel.Default',AxisServlet.java:402)
> .
> .
> .
>
>
> I have been digging through and debugging the source code for a while,
> and I've managed drill down to an exception thrown in the Axis2Util
> class in the org.apache.rampart.util package, in rampart-core-1.4.jar.
> The AxisFault caught in the RampartSender.invoke method above wraps an
> exception, which wraps another exception.. and so on, until I drilled
> down to this class and this method.
>
> I do however fail to understand exactly why it fails, even though I
> also have managed to add a couple of lines of code that make the
> problem go away. I have a hunch it has something to do with the way
> AXIOM works, but I don't know.
>
>
> The code in question is the getDocumentFromSOAPEnvelope method
> (Rampart 1.4). I've added my own comments explaining my findings so
> far in the code below (///// comments):
>
>        /**
>         * Creates a DOM Document using the SOAP Envelope.
>         * @param env An org.apache.axiom.soap.SOAPEnvelope instance
>         * @return Returns the DOM Document of the given SOAP Envelope.
>         * @throws Exception
>         */
>        public static Document getDocumentFromSOAPEnvelope(SOAPEnvelope env,
> boolean useDoom)
>                        throws WSSecurityException {
>                try {
>            if(env instanceof Element) {
>                return ((Element)env).getOwnerDocument();
>            }
>
>            if (useDoom) {
>                env.build();
>
>                // Workaround to prevent a bug in AXIOM where
>                // there can be an incomplete OMElement as the first child body
>                OMElement firstElement = env.getBody().getFirstElement();
>                if (firstElement != null) {
>                    firstElement.build();
>                }
>
>                //Get processed headers
>                SOAPHeader soapHeader = env.getHeader();
>                ArrayList processedHeaderQNames = new ArrayList();
>
>                if(soapHeader != null) {
>                    Iterator headerBlocs = soapHeader.getChildElements();
>                    while (headerBlocs.hasNext()) {
>                        SOAPHeaderBlock element = (SOAPHeaderBlock)
> headerBlocs.next();
>                        if(element.isProcessed()) {
>                            processedHeaderQNames.add(element.getQName());
>                        }
>                    }
>
>                }
>
>                // Check the namespace and find SOAP version and factory
>                String nsURI = null;
>                SOAPFactory factory;
>
>
>                if (env.getNamespace().getNamespaceURI().equals(
>                        SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
>                    nsURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
>                    factory = DOOMAbstractFactory.getSOAP11Factory();
>                } else {
>                    nsURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
>                    factory = DOOMAbstractFactory.getSOAP12Factory();
>                }
>
>
>                ///// I add my own hack here or earlier to make the problem go away.
> See below.
>
>
>                StAXSOAPModelBuilder stAXSOAPModelBuilder = new
> StAXSOAPModelBuilder(env.getXMLStreamReader(), factory, nsURI);
>                SOAPEnvelope envelope = stAXSOAPModelBuilder.getSOAPEnvelope();
>
>
>                /////Adding a toString on the newly built SOAPEnvelope
> object fails with: "Can not serialize OM Element Envelope"
>                /////System.out.println("envelope: " + envelope.toString());
>
>
>                /////This line throws the initial exception
>                ((OMNode) envelope.getParent()).build();
>
>
>
>                //Set the processed flag of the processed headers
>                SOAPHeader header = envelope.getHeader();
>                for (Iterator iter = processedHeaderQNames.iterator(); iter
>                        .hasNext();) {
>                    QName name = (QName) iter.next();
>                    Iterator omKids = header.getChildrenWithName(name);
>                    if(omKids.hasNext()) {
>                        ((SOAPHeaderBlock)omKids.next()).setProcessed();
>                    }
>                }
>
>                Element envElem = (Element) envelope;
>                return envElem.getOwnerDocument();
>            } else {
>                ByteArrayOutputStream baos = new ByteArrayOutputStream();
>                env.build();
>                env.serialize(baos);
>                ByteArrayInputStream bais = new ByteArrayInputStream(baos
>                        .toByteArray());
>                DocumentBuilderFactory factory = DocumentBuilderFactory
>                        .newInstance();
>                factory.setNamespaceAware(true);
>                return factory.newDocumentBuilder().parse(bais);
>            }
>                } catch (Exception e) {
>                        throw new WSSecurityException(
>                                        "Error in converting SOAP Envelope to Document", e);
>                }
>        }
>
>
> Finally, this piece of code added before the StAXSOAPModelBuilder is
> in use makes the problem go away. Why?
>
>                        StringReader rd = new StringReader(env.toString());
>                        XMLStreamReader parser =
> XMLInputFactory.newInstance().createXMLStreamReader(rd);
>                        StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(parser, null);
>                        SOAPEnvelope env2 = (SOAPEnvelope) builder.getDocumentElement();
>                        env = env2;
>
>
> Any insights would be appreciated!
>
> Best Regards,
> Frode Laukus
>