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