Reputation:
I use CXF 3.3.6 with Jetty 9.4.14. Jetty doesn't know about CXF and to link them I use web.xml. In that descriptor I set CXF servlet in which I override loadBus method. When I go to http://127.0.0.1:8080/webservices/calcService?wsdl I see wsdl of the service. These are dependencies I use:
cxf-rt-transports-http-3.3.6.jar
cxf-rt-frontend-jaxws-3.3.6.jar
cxf-core-3.3.6.jar
cxf-rt-frontend-simple-3.3.6.jar
cxf-rt-bindings-soap-3.3.6.jar
cxf-rt-wsdl-3.3.6.jar
cxf-rt-databinding-jaxb-3.3.6.jar
jakarta.xml.ws-api-2.3.2.jar
jakarta.xml.soap-api-1.4.1.jar
jakarta.jws-api-1.1.1.jar
xmlschema-core-2.2.5.jar
istack-commons-runtime-3.0.8.jar
woodstox-core-5.0.3.jar
stax2-api-3.1.4.jar
wsdl4j-1.6.3.jar
//having lost any hope I also added the following:
cxf-rt-bindings-xml-3.3.6.jar
cxf-rt-ws-addr-3.3.6.jar
cxf-rt-ws-policy-3.3.6.jar
cxf-rt-transports-http-jetty-3.3.6.jar
neethi-3.1.1.jar
xml-resolver-1.2.jar
txw2-2.3.2.jar
stax-ex-1.8.3.jar
saaj-impl-1.4.0-b03.jar
mimepull-1.9.7.jar
FastInfoset-1.2.16.jar
jaxb-runtime-2.3.2.jar
jboss-rmi-api_1.0_spec-1.0.6.Final.jar
jacorb-omgapi-3.9.jar
This is my class
@WebService(name="CalculatorService", serviceName="CalculatorService")
public class CalculatorService {
@WebMethod
public double addNumbers(double v1, double v2) {
return v1 + v2;
}
}
This is generated wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="CalculatorService" targetNamespace="http://cfx.foo.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://cfx.foo.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:types>
<xs:schema xmlns:tns="http://cfx.foo.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" targetNamespace="http://cfx.foo.com/" version="1.0">
<xs:element name="addNumbers" type="tns:addNumbers"/>
<xs:element name="addNumbersResponse" type="tns:addNumbersResponse"/>
<xs:complexType name="addNumbers">
<xs:sequence>
<xs:element name="arg0" type="xs:double"/>
<xs:element name="arg1" type="xs:double"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="addNumbersResponse">
<xs:sequence>
<xs:element name="return" type="xs:double"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="addNumbers">
<wsdl:part name="parameters" element="tns:addNumbers">
</wsdl:part>
</wsdl:message>
<wsdl:message name="addNumbersResponse">
<wsdl:part name="parameters" element="tns:addNumbersResponse">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="CalculatorService">
<wsdl:operation name="addNumbers">
<wsdl:input name="addNumbers" message="tns:addNumbers">
</wsdl:input>
<wsdl:output name="addNumbersResponse" message="tns:addNumbersResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CalculatorServiceSoapBinding" type="tns:CalculatorService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="addNumbers">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="addNumbers">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="addNumbersResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CalculatorService">
<wsdl:port name="CalculatorServicePort" binding="tns:CalculatorServiceSoapBinding">
<soap:address location="http://localhost:9090/CalculatorServicePort"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Upon generated wsdl I generate (using plugin) java client stubs. The problem is that when via client I try to call my service my arguments for method are ignored. This is what I see using ngrep:
T 127.0.0.1:33602 -> 127.0.0.1:8080 [AP]
POST /webservices/calcService HTTP/1.1..Content-Type: text/xml; charset=UTF-8..Accept: */*..SOAPAction: ""..User-Agent: Apache-CXF/3.3.6.
.Cache-Control: no-cache..Pragma: no-cache..Host: 127.0.0.1:8080..Connection: keep-alive..Content-Length: 218....
##
T 127.0.0.1:33602 -> 127.0.0.1:8080 [AP]
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:addNumbers xmlns:ns2="http://cfx.foo.com/"><arg0>1.2</arg0><arg1>1.2</arg1></ns2:addNumbers></soap:Body></soap:Envelope>
##
T 127.0.0.1:8080 -> 127.0.0.1:33602 [AP]
HTTP/1.1 500 Server Error..Date: Thu, 30 Apr 2020 15:38:13 GMT..Content-Type: text/xml;charset=utf-8..Content-Length: 322..Server: Jetty(
9.4.z-SNAPSHOT)....<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Server</f
aultcode><faultstring>null while invoking public double com.foo.cfx.CalculatorService.addNumbers(double,double) with params [
null, null].</faultstring></soap:Fault></soap:Body></soap:Envelope>
#######
As you see both arguments for addNumbers are passed but they are ignored.
And this is the stack
org.apache.cxf.interceptor.Fault: null while invoking public double com.temp.cfx.CalculatorService.addNumbers(double,double) with params [null, null].
at [email protected]/org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:166)
at [email protected]/org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:140)
at [email protected]/org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:74)
at [email protected]/org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at [email protected]/org.apache.cxf.interceptor.ServiceInvokerInterceptor$2.run(ServiceInvokerInterceptor.java:126)
at [email protected]/org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
at [email protected]/org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:131)
at [email protected]/org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at [email protected]/org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at [email protected]/org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
at [email protected]/org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
at [email protected]/org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
at [email protected]/org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
at [email protected]/org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225)
at [email protected]/org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301)
at [email protected]/org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220)
at [email protected]/javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at [email protected]/org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:276)
Could anyone help to solve this problem?
I did a test project that can be run by mvn install
here.
Upvotes: 2
Views: 1738
Reputation: 75914
Looks you have incorrect namespace based on wsdl
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:addNumbers xmlns:ns2="http://webapp.mycompany.com/">
<ns2:v1>1.2</ns2:v1>
<ns2:v2>1.2</ns2:v2>
</ns2:addNumbers>
</soap:Body>
</soap:Envelope>
Update
Server method
@WebService(name="CalculatorService",
serviceName="CalculatorService")
public class CalculatorService {
@WebMethod
public double addNumbers(@WebParam(name="value1") double v1, @WebParam(name="value2") double v2) {
return v1 + v2;
}
}
In your case cxf-java2ws-plugin
was generating a WSDL document ( the same one you are referring in your integration test ) was the one with JAX WS annotation. Note below the WSDL generated by plugin and the actual wsdl used by service. Pay attention to the element form defaults and local elements.
Plugin Generated WSDL
<xs:schema xmlns:tns="http://webapp.mycompany.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" targetNamespace="http://webapp.mycompany.com/" version="1.0">
<xs:element name="addNumbers" type="tns:addNumbers"/>
<xs:complexType name="addNumbers">
<xs:sequence>
<xs:element name="value1" type="xs:double"/>
<xs:element name="value2" type="xs:double"/>
</xs:sequence>
</xs:complexType>
Service Actual WSDL ( with ServerFactoryBean
doesn't take JAX WS annotation into account)
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://webapp.mycompany.com/" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://webapp.mycompany.com/">
<xsd:element name="addNumbers" type="tns:addNumbers"/>
<xsd:complexType name="addNumbers">
<xsd:sequence>
<xsd:element name="v1" type="xsd:double"/>
<xsd:element name="v2" type="xsd:double"/>
</xsd:sequence>
</xsd:complexType>
So your request was failing from integration test as server doesn't understand the request being sent.
Fix was to use JaxWsServerFactoryBean
when initializing servlet. Now the service wsdl matches what was generated by plugin.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://webapp.mycompany.com/" elementFormDefault="unqualified" targetNamespace="http://webapp.mycompany.com/" version="1.0">
<xs:element name="addNumbers" type="tns:addNumbers"/>
<xs:complexType name="addNumbers">
<xs:sequence>
<xs:element name="value1" type="xs:double"/>
<xs:element name="value2" type="xs:double"/>
</xs:sequence>
</xs:complexType>
Upvotes: 1