I'm encountering problems with the wsdl first approach when attempting
to use ws-addressing types such as ReplyTo in soap headers. Consider
the following wsdl:
<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions name="AsyncProcessService"
targetNamespace="http://mycompany.com/asyncwsa"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://mycompany.com/asyncwsa"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="unqualified"
targetNamespace="http://mycompany.com/asyncwsa"
xmlns="http://mycompany.com/asyncwsa"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.1">
<!--
<xs:import
namespace="http://www.w3.org/2005/08/addressing"
schemaLocation="schemas/wsdl/ws-addr.xsd" />
-->
<xs:complexType name="AsyncProcessRequest">
<xs:sequence>
<xs:element minOccurs="0" name="id"
type="xs:long" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="AsyncProcessResponse">
<xs:sequence>
<xs:element minOccurs="0" name="name"
type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="asyncProcessRequest" nillable="true"
type="AsyncProcessRequest" />
<xs:element name="asyncProcessResponse" nillable="true"
type="AsyncProcessResponse" />
<xs:element name="timestamp" type="xs:dateTime" />
</xs:schema>
</wsdl:types>
<wsdl:message name="processResponseMsg">
<wsdl:part element="tns:asyncProcessResponse"
name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="processMsg">
<wsdl:part element="tns:asyncProcessRequest"
name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="headerMsg">
<wsdl:part name="header" element="wsa:ReplyTo" />
<!--
<wsdl:part name="header" element="tns:timestamp" />
-->
</wsdl:message>
<wsdl:portType name="AsyncProcess">
<wsdl:operation name="process">
<wsdl:input message="tns:processMsg" name="process">
</wsdl:input>
<wsdl:output message="tns:processResponseMsg"
name="processResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="AsyncProcessSoapBinding"
type="tns:AsyncProcess">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="process">
<wsa:UsingAddressing />
<soap:operation
soapAction="http://mycompany.com/asyncws/process" style="document" />
<wsdl:input name="process">
<soap:header message="tns:headerMsg"
part="header"
use="literal" />
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="processResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="AsyncProcessService">
<wsdl:port binding="tns:AsyncProcessSoapBinding"
name="AsyncProcessPort">
<soap:address
location="http://localhost:7003/asyncwsa/AsyncProcess" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Generating sources from the wsdl with cxf-codegen-plugin (with
exsh=true) yields the following exception:
[INFO] Failed to create java parameter for part [header] in method
[process] - this wsdl is invalid, please use the wsdl
validator tool to validate this wsdl
[INFO] ------------------------------------------------------------------------
[DEBUG] Trace
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to
create java parameter for part [header] in method [pro
cess] - this wsdl is invalid, please use the wsdlvalidator tool to
validate this wsdl
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:564)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:48
0)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:459)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.jav
a:311)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:278)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:143)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:333)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:126)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:282)
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.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.MojoExecutionException: Failed to
create java parameter for part [header] in method [
process] - this wsdl is invalid, please use the wsdlvalidator tool to
validate this wsdl
at
org.apache.cxf.maven_plugin.WSDL2JavaMojo.processWsdl(WSDL2JavaMojo.java:296)
at
org.apache.cxf.maven_plugin.WSDL2JavaMojo.execute(WSDL2JavaMojo.java:202)
at
org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:447)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:539)
... 16 more
Caused by: org.apache.cxf.tools.common.ToolException: Failed to create
java parameter for part [header] in method [proce
ss] - this wsdl is invalid, please use the wsdlvalidator tool to
validate this wsdl
at
org.apache.cxf.tools.common.model.JavaMethod.addParameter(JavaMethod.java:155)
at
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ParameterProcessor.addParameter(ParameterProces
sor.java:113)
at
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ParameterProcessor.processInput(ParameterProces
sor.java:184)
at
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ParameterProcessor.buildParamModelsWithoutOrder
ing(ParameterProcessor.java:497)
at
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ParameterProcessor.process(ParameterProcessor.j
ava:81)
at
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.OperationProcessor.processMethod(OperationProce
ssor.java:91)
at
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.OperationProcessor.process(OperationProcessor.j
ava:63)
at
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.PortTypeProcessor.process(PortTypeProcessor.jav
a:128)
at
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.WSDLToJavaProcessor.wsdlDefinitionToJavaModel(WSDLToJava
Processor.java:88)
at
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.WSDLToJavaProcessor.process(WSDLToJavaProcessor.java:60)
at
org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:197)
at
org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:232)
at
org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:83)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:103)
at
org.apache.cxf.maven_plugin.WSDL2JavaMojo.processWsdl(WSDL2JavaMojo.java:292)
... 19 more
Despite the wording of the exception, according to the wsdlvalidator
the wsdl is valid.
When testing the rendering of headers by replacing the ws-addressing
ReplyTo type with another type, such as xs:dateTime, the request
wrapper is correctly generated:
@WebService(targetNamespace = "http://mycompany.com/asyncwsa", name =
"AsyncProcess")
@XmlSeeAlso({ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface AsyncProcess {
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@WebResult(name = "asyncProcessResponse", targetNamespace =
"http://mycompany.com/asyncwsa", partName = "parameters")
@WebMethod(action = "http://mycompany.com/asyncws/process")
public AsyncProcessResponse process(
@WebParam(partName = "parameters", name =
"asyncProcessRequest", targetNamespace =
"http://mycompany.com/asyncwsa")
AsyncProcessRequest parameters,
@WebParam(partName = "header", name = "timestamp",
targetNamespace = "http://mycompany.com/asyncwsa", header = true)
javax.xml.datatype.XMLGregorianCalendar header
);
}
Additionally, when I use ws-addressing types in the element acting as
the soap body, I have no problems, and the request wrapper is again
correctly rendered.
FWIW, while stepping through the code I have noticed that the method
String
org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBDataBinding.getType(QName
qname, boolean element) returns null when processing the ReplyTo
header part. I'm unsure whether or not this is symptomatic of an
incorrectly initialized JAXB context.
Can anyone help identify the problem and resolve it?
Regards,
Callum.