I have an issue with schema validation that I believe is related to
bug https://issues.apache.org/jira/browse/CXF-3233
Here's the full story, log files, and a workaround.
I have a jaxws:endpoint configured to use a wsdlLocation in a Jar file
(real namespaces etc removed):
<jaxws:endpoint xmlns:my="urn://my.namespace"
address="jms://"
transportId="http://cxf.apache.org/transports/jms"
serviceName="my:service" endpointName="my:port"
implementor="#myImplementor"
wsdlLocation="jar:file:WEB-INF/lib/my.jar!/path/to/my.wsdl"> ...
With turn schema validation off, everything is fine.
When I enable schema validation (<entry
key="schema-validation-enabled" value="true" />) incoming requests are
validated and accepted / rejected as expected.
When a valid request comes in and passes validation, I can see it's
getting into the code, and the code is returning successfully.
However, after the code returns, nothing comes back from CXF. It's a
complete blank.
As per Dan's suggestion on IRC, I turned on logging at the root-trace
level and added a custom OutInterceptor to see what was happening.
I created an interceptor that loops through the available interceptors
and prints them out:
public void handleMessage(SoapMessage message) throws Fault {
log.debug("--- HELLO OUT INTERCEPTOR handleMessage ! ---");
for( Interceptor<? extends Message> interceptor :
message.getInterceptorChain() )
debug.log("FOUND INTERCEPTOR:" + interceptor.getClass().getName());
}
}
===== Begin log for interceptors with schema-validation=true =====
--- HELLO OUT INTERCEPTOR handleMessage ! ---
Message.toString():{org.apache.cxf.interceptor.LoggingOutInterceptor.log-setup=true,
javax.xml.ws.wsdl.operation= .... JMSMessage class: jms_text
JMSType: null
JMSDeliveryMode: 2
[...]
JMS_IBM_PutTime: 00320622
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="urn://my.ns ..., org.apache.cxf.mime.headers={}}
>>>> FOUND INTERCEPTOR:org.apache.cxf.jaxws.interceptors.HolderOutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.jaxws.interceptors.SwAOutInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.binding.soap.interceptor.SoapHeaderOutFilterInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.MessageSenderInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.LoggingOutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.AttachmentOutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.StaxOutInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor
>>>> FOUND INTERCEPTOR:com.td.war.OutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.BareOutInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor$SoapOutEndingInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.interceptor.StaxOutInterceptor$StaxOutEndingInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor
Invoking handleMessage on interceptor
org.apache.cxf.interceptor.BareOutInterceptor@51955195
Invoking handleMessage on interceptor
org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor$SoapOutEndingInterceptor@7db87db8
Invoking handleMessage on interceptor
org.apache.cxf.interceptor.StaxOutInterceptor$StaxOutEndingInterceptor@272f272f
Invoking handleMessage on interceptor
org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@52a552a5
Outbound Message
---------------------------
ID: 1
Encoding: UTF-8
Content-Type: text/xml
Headers
Payload: <soap:Envelope> .... lots of XML here, looks good! ...</soap:Envelope>
===== End log for interceptors with schema-validation=true =====
Now here's what happens when I turn schema validation on:
===== Begin log for interceptors with schema-validation=true =====
Invoking handleMessage on interceptor com.td.war.OutInterceptor@30fc30fc
--- HELLO OUT INTERCEPTOR handleMessage ! ---
Message.toString():{org.apache.cxf.interceptor.LoggingOutInterceptor.log-setup=
[...] JMSMessage class: jms_text
JMSType: null
JMSDeliveryMode: 2
[...]
JMS_IBM_PutTime: 01030155
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="urn://my.ns ..., org.apache.cxf.mime.headers={}}
========== CHECKING THE INTERCEPTORS: START ===========
>>>> FOUND INTERCEPTOR:org.apache.cxf.jaxws.interceptors.HolderOutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.jaxws.interceptors.SwAOutInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.binding.soap.interceptor.SoapHeaderOutFilterInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.MessageSenderInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.LoggingOutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.AttachmentOutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.StaxOutInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor
>>>> FOUND INTERCEPTOR:com.td.war.OutInterceptor
>>>> FOUND INTERCEPTOR:org.apache.cxf.interceptor.BareOutInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor$SoapOutEndingInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.interceptor.StaxOutInterceptor$StaxOutEndingInterceptor
>>>> FOUND
>>>> INTERCEPTOR:org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor
========== CHECKING THE INTERCEPTORS: END ===========
Invoking handleMessage on interceptor
org.apache.cxf.interceptor.BareOutInterceptor@2a262a26
Invoking handleFault on interceptor
org.apache.cxf.interceptor.BareOutInterceptor@2a262a26
Invoking handleFault on interceptor com.td.war.OutInterceptor@30fc30fc
Invoking handleFault on interceptor
org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor@2ac12ac1
Invoking handleFault on interceptor
org.apache.cxf.interceptor.StaxOutInterceptor@29ee29ee
Invoking handleFault on interceptor
org.apache.cxf.interceptor.AttachmentOutInterceptor@29d329d3
Invoking handleFault on interceptor
org.apache.cxf.interceptor.LoggingOutInterceptor@166d166d
Invoking handleFault on interceptor
org.apache.cxf.interceptor.MessageSenderInterceptor@2b2a2b2a
Invoking handleFault on interceptor
org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor@2ab02ab0
Invoking handleFault on interceptor
org.apache.cxf.binding.soap.interceptor.SoapHeaderOutFilterInterceptor@2a002a00
Invoking handleFault on interceptor
org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor@2c782c78
Invoking handleFault on interceptor
org.apache.cxf.jaxws.interceptors.SwAOutInterceptor@2c312c31
Invoking handleFault on interceptor
org.apache.cxf.jaxws.interceptors.HolderOutInterceptor@2c882c88
Interceptor for {urn://my.ns}MyService#{urn://my.ns}myCode has thrown
exception, unwinding now
org.apache.cxf.interceptor.Fault: Marshalling Error: cvc-elt.1: Cannot
find the declaration of element '[...]'.
at
org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:256)
at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:169)
[...]
Caused by:
javax.xml.bind.MarshalException
- with linked exception:
[org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration
of element [<-- the parser can't find my XSD]
[...]
Invoking handleMessage on interceptor
org.apache.cxf.binding.soap.interceptor.Soap11FaultOutInterceptor$Soap11FaultOutInterceptorInternal@40824082
Invoking handleMessage on interceptor
org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor$SoapOutEndingInterceptor@36f036f
Invoking handleMessage on interceptor
org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@2b512b51
Payload to be sent out is :[]
send out the message!
server sending reply:
===== End log for interceptorswith schema-validation=true =====
You can see that the payload is empty which explains the blank
response I get when I turn validation on.
It's like the payload got lost somewhere along the way with the
exception being thrown.
I imagine what's happening is that on the outbound validation, it
can't find any XSD's to validate against.
I tried to remedy this by explicitly telling it where to find the
schemas that are in the jar (which would be duplicate code):
<jaxws:endpoint [...]
wsdlLocation="jar:file:WEB-INF/lib/my.jar!/path/to/my.wsdl"> ...
<jaxws:schemaLocations>
<jaxws:schemaLocation>jar:file:WEB-INF/lib/my.jar!/path/to/1.xsd</jaxws:schemaLocation>
<jaxws:schemaLocation>jar:file:WEB-INF/lib/my.jar!/path/to/2.xsd</jaxws:schemaLocation>
etc.
</jaxws:schemaLocations>
But that did not work.
What does work for my purposes is disabling schema validation in an
outbound interceptor.
I read through the code for
org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor and
basically just reverse engineered this from the "shouldValidate()"
method
which checks on Message.SCHEMA_VALIDATION_ENABLED:
public final class SchemaValidationDisablingOutboundInterceptor
extends AbstractSoapInterceptor
{
public SchemaValidatingOutbountInterceptor() {
super(Phase.MARSHAL);
}
public void handleMessage(SoapMessage message) throws Fault {
for( Interceptor<? extends Message> interceptor :
message.getInterceptorChain() ) {
message.setContextualProperty(Message.SCHEMA_VALIDATION_ENABLED,
false);
}
}
}
-Jeff