I've been working for a few days on a problem with a WSDL we've defined. We are using wsimport to generate code from the WSDL and then using that to run a service. During WSImport, 2 elements cannot be resolved somehow which throws warnings. Runtime however, these warnings turn into errors and we cannot run our service. How can we get rid of these warnings and therefore errors?
All pointers will be greatly appreciated.
We are using Metro 2.3 and Java 7.
The WSDL is using xsds from the HR-XML specification, but I trimmed them down to display the problem clearer.
wsimport is reporting:
MacBook-Pro-van-Martin:WSDL-problem sunsear$ wsimport -Xnocompile -s generated "file:DummyService.wsdl"
parsing WSDL...
[WARNING] src-resolve: Cannot resolve the name 'hr:Assignment' to a(n) 'element declaration' component.
line 14 of file:xsd/AssignmentRequestElement.xsd
[WARNING] src-resolve: Cannot resolve the name 'hr:HumanResource' to a(n) 'element declaration' component.
line 15 of file:xsd/AssignmentRequestElement.xsd
Generating code...
WSimport is complaining about hr:Assignment and hr:HumanResource which are referenced in the AssignmentRequestElement.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://personnel.services.com/services/2013-10"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:hr="http://ns.hr-xml.org/2007-04-15"
targetNamespace="http://personnel.services.com/services/2013-10"
elementFormDefault="qualified" version="2013-10">
<xsd:import namespace="http://ns.hr-xml.org/2007-04-15" schemaLocation="HR-XML-2_5/SIDES/Assignment.xsd"/>
<xsd:import namespace="http://ns.hr-xml.org/2007-04-15" schemaLocation="HR-XML-2_5/SIDES/HumanResource.xsd"/>
<xsd:element name="AssignmentRequestElement">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="hr:Assignment"/>
<xsd:element ref="hr:HumanResource" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
HumanResource looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ns.hr-xml.org/2007-04-15"
targetNamespace="http://ns.hr-xml.org/2007-04-15" elementFormDefault="qualified" version="2007-04-15">
<xsd:complexType name="HumanResourceType">
<xsd:sequence>
<xsd:element name="HumanResourceId" type="xsd:string" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="HumanResource" type="HumanResourceType"/>
</xsd:schema>
Assignment looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://ns.hr-xml.org/2007-04-15" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://ns.hr-xml.org/2007-04-15" elementFormDefault="qualified" version="2007-04-15">
<xsd:complexType name="AssignmentType">
<xsd:sequence>
<xsd:element name="AssignmentId" type="xsd:string" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="Assignment" type="AssignmentType"/>
</xsd:schema>
For completeness, this is the WSDL itself:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:tns="http://personnel.services.com/services/2013-10"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:hr="http://ns.hr-xml.org/2007-04-15" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://personnel.services.com/services/2013-10">
<wsdl:types>
<xsd:schema
elementFormDefault="qualified">
<xsd:import namespace="http://ns.hr-xml.org/2007-04-15"
schemaLocation="xsd/HR-XML-2_5/CPO/Acknowledgement.xsd"/>
<xsd:import namespace="http://personnel.services.com/services/2013-10"
schemaLocation="xsd/AssignmentRequestElement.xsd"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="AssignmentRequest">
<wsdl:documentation>A generic request of type Assignment (A) or Assignment+HumanResource (A+HR).
</wsdl:documentation>
<wsdl:part name="input" element="tns:AssignmentRequestElement"/>
</wsdl:message>
<wsdl:message name="Response">
<wsdl:documentation>A generic response of type Acknowledgement.</wsdl:documentation>
<wsdl:part name="output" element="hr:Acknowledgement"/>
</wsdl:message>
<wsdl:portType name="DummyService">
<wsdl:operation name="ProcessAssignment">
<wsdl:documentation>ProcessAssignment is used to send details of an Assignment
The request message is an Assignment (A) or
an Assignment+HumanResource (A+HR) message.
</wsdl:documentation>
<wsdl:input message="tns:AssignmentRequest"/>
<wsdl:output message="tns:Response"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SoapServiceHttpBinding" type="tns:DummyService">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="ProcessAssignment">
<wsdlsoap:operation soapAction="https://dummy.personnel.services.com/ws/DummySoapService/ProcessAssignment"
style="document"/>
<wsdl:input>
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DummySoapService">
<wsdl:port name="DummyServicesEndpoint" binding="tns:SoapServiceHttpBinding">
<wsdlsoap:address location="https://dummy.personnel.services.com/ws/DummySoapService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
The WSDL and XSDs are correct according to SoapUI and XMLSpy, they validate messages correctly.
The wsdl and xsds can be downloaded here:
https://www.dropbox.com/sh/t8klaoodjfsd772/G2MBGZxLE_
You have assigned 2 different schema-locations to the same namespaces URL. That could be the reason of this error, because now wsimport does not know where to search for hr: objects.
<xsd:import namespace="http://ns.hr-xml.org/2007-04-15" schemaLocation="HR-XML-2_5/SIDES/Assignment.xsd"/>
<xsd:import namespace="http://ns.hr-xml.org/2007-04-15" schemaLocation="HR-XML-2_5/SIDES/HumanResource.xsd"/>
Have a look at this stackoverflow question for solving this problem:
SAXParseException; src-resolve: Cannot resolve the name '...' to a(n) 'type definition' component
Related
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 org.apache.cxf.core#3.3.6/org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:166)
at org.apache.cxf.core#3.3.6/org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:140)
at org.apache.cxf.core#3.3.6/org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:74)
at org.apache.cxf.core#3.3.6/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 org.apache.cxf.core#3.3.6/org.apache.cxf.interceptor.ServiceInvokerInterceptor$2.run(ServiceInvokerInterceptor.java:126)
at org.apache.cxf.core#3.3.6/org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
at org.apache.cxf.core#3.3.6/org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:131)
at org.apache.cxf.core#3.3.6/org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.core#3.3.6/org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http#3.3.6/org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
at org.apache.cxf.transport.http#3.3.6/org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
at org.apache.cxf.transport.http#3.3.6/org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
at org.apache.cxf.transport.http#3.3.6/org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
at org.apache.cxf.transport.http#3.3.6/org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225)
at org.apache.cxf.transport.http#3.3.6/org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301)
at org.apache.cxf.transport.http#3.3.6/org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220)
at javax.servlet.api#3.1.0/javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.apache.cxf.transport.http#3.3.6/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.
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>
I'm implementing a simple client using apache cxf and the codegen maven plugin (both release 3.1.11).
Here is my sample wsdl:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:webServiceTest" xmlns:s0="urn:webServiceTest" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema elementFormDefault="qualified" targetNamespace="urn:webServiceTest">
<xsd:element name="OpenTk" type="s0:InputMapping1"/>
<xsd:complexType name="InputMapping1">
<xsd:sequence>
<xsd:element minOccurs="0" name="ID_NOTIFICA" type="xsd:string"/>
<xsd:element minOccurs="0" name="ID_MESSAGGIO" type="xsd:string"/>
<xsd:element minOccurs="0" name="DATA_ID_NOTIFICA" type="xsd:dateTime"/>
<xsd:element minOccurs="0" name="DATA_ID_MESSAGGIO" type="xsd:dateTime"/>
<xsd:element minOccurs="0" name="ID_RISORSA" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="APERTURATKResponse" type="s0:OutputMapping1"/>
<xsd:complexType name="OutputMapping1">
<xsd:sequence>
<xsd:element minOccurs="0" name="CODICE" type="xsd:string"/>
<xsd:element minOccurs="0" name="DESCRIZIONE" type="xsd:string"/>
<xsd:element minOccurs="0" name="NOTE" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="AuthenticationInfo" type="s0:AuthenticationInfo"/>
<xsd:complexType name="AuthenticationInfo">
<xsd:sequence>
<xsd:element name="userName" type="xsd:string"/>
<xsd:element name="password" type="xsd:string"/>
<xsd:element minOccurs="0" name="authentication" type="xsd:string"/>
<xsd:element minOccurs="0" name="locale" type="xsd:string"/>
<xsd:element minOccurs="0" name="timeZone" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="OpenTkSoapOut">
<wsdl:part element="s0:APERTURATKResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="OpenTkSoapIn">
<wsdl:part element="s0:OpenTk" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="ARAuthenticate">
<wsdl:part element="s0:AuthenticationInfo" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="New_Port_0PortType">
<wsdl:operation name="OpenTk">
<wsdl:input message="s0:OpenTkSoapIn">
</wsdl:input>
<wsdl:output message="s0:OpenTkSoapOut">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="New_Port_0SoapBinding" type="s0:New_Port_0PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="OpenTk">
<soap:operation soapAction="urn:webServiceTest/OpenTk" style="document"/>
<wsdl:input>
<soap:header message="s0:ARAuthenticate" part="parameters" use="literal">
</soap:header>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="WebServicesFWCFFService">
<wsdl:port binding="s0:New_Port_0SoapBinding" name="New_Port_0Soap">
<soap:address location="http://localhost:9090/testService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I need to change client endpoint so I decided to use cxf.frontend feature. I created a simple Client and I used the api to set the address property.
Here is the code:
QName SERVICE = new QName("urn:webServiceTest", "WebServicesFWCFFService");
URL url = this.getClass().getClassLoader().getResource("testWsdl.wsdl").toURI().toURL();
NewPort0PortType portType = new WebServicesFWCFFService(url, SERVICE).getNewPort0Soap();
Client client = ClientProxy.getClient(portType);
client.getRequestContext().put(Message.ENDPOINT_ADDRESS,address);
Then inside my unit tests I try to invoke the service (the service created by codegen plugin) doing:
ClientTest client = new ClientTest();
Holder<String> code= new Holder<>();
Holder<String> description= new Holder<>();
Holder<String> notes= new Holder<>();
client.portType.openTk("12","",
null,null,"1",code, description, notes);
assertNotNull(notes.value);
assertNotNull(code.value);
but I receive a soap fault org.apache.cxf.binding.soap.SoapFault: wrong number of arguments while invoking public void it.test.cxf.impl.New_Port_0SoapImpl.openTk.
I found that the problem seems to be inside org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor and in particular when this interceptor create a WrapperHelper class using the method getHelperWrapper.
Then uses this wrapper to create the object using the ObjectFactory created by codegen plugin (createWrapperObject(objs);). This results in a new InputMappin1 object with all filds null.
Can someone explane me this behaviour and how I can avoid this? Do I need to implement some kind of custom interceptor or I'm missing some configuration?
I know this is an old question, but here is my 2 cents.
As you said, this seems a bug in cxf. I got the same error exposing a SOAP service with JBoss, using JAX-WS annotations in source code (my approach is contract-last, I start with an annotated java class and let cxf generate the service with its WSDL).
To overcome the problem, I specified the SOAP binding style as DOCUMENT, and parameters style as WRAPPED.
I used JAX WS annotation on the Service class:
#WebService
#SOAPBinding(
style = SOAPBinding.Style.DOCUMENT,
parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
public class MySoapService
You can read more details about SOAP bindings here.
Anyway, this changes the structure of XML messages, but cxf will handle all the details for you.
I've made a WSDL file and I intend to create top down web service out of it. Unfortunately, Eclipse throws this error:
"A problem occurred while running the WSDL validator for namespace http://schemas.xmlsoap.org/wsdl/"
I've made some research and it looks like it's happening because of some Eclipse wsdl-validation bug, explained here
Some guy there claims that he fixed this error with patch, and I've applied it, but the error stays and I'm starting to think that there's some problem with my wsdl file itself.
WebService is supposed to take a list(column) of ID's and return a 2-column table data based on those ID's.
Can you help me find out what is wrong with it?
Eclipse Java EE IDE for Web Developers.
Version: Mars.2 Release (4.5.2)
Build id: 20160218-0600
WTP 1.2.1.20150819-2220
Here's WSDL file:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
targetNamespace="reb.ecm.ws.RebUtilsService"
xmlns="reb.ecm.ws.RebUtilsService"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:complexType name='DPList'>
<xsd:element
minOccurs='0'
maxOccurs='unbounded'
name='DP'
type='DP'/>
</xsd:complexType>
<xsd:complexType name='DP'>
<xsd:all>
<xsd:element
minOccurs='0'
maxOccurs='1'
name='DPID'
type='xsd:int'/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name='WSInfoList'>
<xsd:element
minOccurs='0'
maxOccurs='unbounded'
name='WSInfoItem'
type='WSInfoItem'/>
</xsd:complexType>
<xsd:complexType name='WSInfoItem'>
<xsd:all>
<xsd:element
minOccurs='0'
maxOccurs='1'
name='DPID'
type='xsd:int'/>
</xsd:all>
<xsd:all>
<xsd:element
minOccurs='0'
maxOccurs='1'
name='WSID'
type='xsd:int'/>
</xsd:all>
</xsd:complexType>
</wsdl:types>
<wsdl:message name="inMessage">
<wsdl:part name="DPList" type="DPList" />
</wsdl:message>
<wsdl:message name="outMessage">
<wsdl:part name="WSInfoList" type="WSInfoList" />
</wsdl:message>
<wsdl:portType name="RebUtilsServicePortType">
<wsdl:operation name="GetActualWSIDbyDPID" >
<wsdl:input message="inMessage" />
<wsdl:output message="outMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="RebUtilsServiceHTTPBinding"
type="RebUtilsServicePortType">
<wsdlsoap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetActualWSIDbyDPID">
<wsdlsoap:operation soapAction=""/>
<wsdl:input>
<wsdlsoap:body use="literal" />
</wsdl:input>
<wsdl:output>
<wsdlsoap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="RebUtilsServicePorts">
<wsdl:port binding="RebUtilsServiceHTTPBinding" name="RebUtilsService">
<wsdlsoap:address
location="http://localhost:9084/RebUtilsService/RebUtilsServicePorts"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
UPDATE: There were no problem with Eclipse. At least patch, mentioned earlier fixed something.
Answer
Your schema is not properly defined. Please see the below image.
Kindly change it to your corrected datatype element which is defined in your schema definitions, Please change in Eclipse WSDL Design view.
Regenerate your client and let know the results.
You should have seperate XSD schema files and should be mapped based on your requirement, that's why it is failing and please have a look into the exploded design view.
General Rule
While creating a SOAP Service, Please define your required input/output XSD schemas
Using schema as in input you need to generate the WSDL file using your IDE/Maven/any build tool.
For easier manipulations/Edits, please choose Eclipse WSDL Editor.
In my WSDL I have an operation
<wsdl:operation name="theMethod">
<wsdl:input message="input1" name="input1"></wsdl:input>
<wsdl:output message="tns:classNumber1" name="classNumber1"></wsdl:output>
</wsdl:operation>
in my xsd, classNumber1 is a complex type and it is a wrapper for another type: classNumber2
<xs:complexType name="classNumber1">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="tns:classNumber2"/>
</xs:sequence>
</xs:complexType>
when I generate classes with cxf (I use cxf maven plugin), I expected that theMethod to return a ClassNumber1 but it was a ClassNumber2.
#WebMethod
#ResponseWrapper(localName="classNumber1" , className="com.model.ClassNumber")
public ClassNumber2 theMethod (Input1 input1){
...
}
Is there a way to tell cxf to generate the method with the wrapper CLassNumber1.
Thanks.
I find the solution in this doc, question "How can I switch my generated web service method calls from wrapper style to non wrapper-style (or vice-versa)?"
The solution to keep wrappers with cxf generation is to add a binding file in the pom.xml:
<defaultOptions>
<bindingFiles>
<bindingFile>${basedir}/src/main/resources/bindings.xjb</bindingFile>
</bindingFiles>
<noAddressBinding>true</noAddressBinding>
</defaultOptions>
In the binding file you set enableWrapperStyle to false:
<jaxws:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<enableWrapperStyle>false</enableWrapperStyle>
</jaxws:bindings>
Based on the information you have provided I have created a basic interface as shown below.
this works as per your expectation.
<xsd:complexType name="input1">
<xsd:sequence>
<xsd:element name="in" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ClassNumber1">
<xsd:sequence>
<xsd:element minOccurs="0" name="out" type="tns:ClassNumber2" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ClassNumber2">
<xsd:sequence>
<xsd:element name="out" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="input1">
<wsdl:part element="tns:input1" name="parameters" />
</wsdl:message>
<wsdl:message name="ClassNumber1">
<wsdl:part element="tns:ClassNumber1" name="parameters" />
</wsdl:message>
<wsdl:portType name="NewWSDLFile">
<wsdl:operation name="NewOperation">
<wsdl:input message="tns:input1" />
<wsdl:output message="tns:ClassNumber1" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="NewWSDLFileSOAP" type="tns:NewWSDLFile">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="NewOperation">
<soap:operation soapAction="http://www.example.org/NewWSDLFile/NewOperation" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="NewWSDLFile">
<wsdl:port binding="tns:NewWSDLFileSOAP" name="NewWSDLFileSOAP">
<soap:address location="http://www.example.org/" />
</wsdl:port>
</wsdl:service>
Please check <wsdl:output message="tns:ClassNumber1" />
I believe you have given the wrong in your output information in your
<wsdl:message name="ClassNumber1">
<wsdl:part element="tns:ClassNumber1" name="parameters" />
</wsdl:message>
Hope this helps.
I have written a WSDL to generate the Stubs and skeleton but my skeletons are not getting generated in the eclipse. I am using Helios version of Eclipse.
Can any one tell what is the issue with WSDL?
I want to use Axis 2. I tried to generate the skeleton using wsdl2java also but it gives compilation issues in the generated classes. I am not able to attach the file here so I am pasting it here.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:impl="http://DefaultNamespace"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
name="Test" targetNamespace="http://DefaultNamespace">
<wsdl:types>
<xsd:schema elementFormDefault="qualified"
targetNamespace="http://DefaultNamespace" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://xml.apache.org/xml-soap" />
<xsd:element name="serviceMethod">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="vo" type="impl:MyVo" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="MyVo">
<xsd:sequence>
<xsd:element name="name" nillable="false" type="xsd:string" />
<xsd:element name="params" nillable="true"
type="apachesoap:Map" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="serviceMethodResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="serviceMethodReturn" type="impl:MyVo" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<xsd:schema elementFormDefault="qualified"
targetNamespace="http://xml.apache.org/xml-soap" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://DefaultNamespace" />
<xsd:complexType name="mapItem">
<xsd:sequence>
<xsd:element name="key" nillable="true" type="xsd:anyType" />
<xsd:element name="value" nillable="true" type="xsd:anyType" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Map">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0"
name="item" type="apachesoap:mapItem" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="serviceMethodRequest">
<wsdl:part element="impl:serviceMethod" name="parameters" />
</wsdl:message>
<wsdl:message name="serviceMethodResponse">
<wsdl:part element="impl:serviceMethodResponse" name="parameters" />
</wsdl:message>
<wsdl:portType name="Test">
<wsdl:operation name="serviceMethod">
<wsdl:input message="impl:serviceMethodRequest" name="serviceMethodRequest" />
<wsdl:output message="impl:serviceMethodResponse" name="serviceMethodResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TestSOAP" type="impl:Test">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="serviceMethod">
<soap:operation soapAction="http://DefaultNamespace/serviceMethod" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Test">
<wsdl:port binding="impl:TestSOAP" name="MyWebService">
<soap:address location="http://localhost:8080/Temp/services/MyService" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
That's a problem with your install.
Download and verify axis2 and the axis2 eclipse plugins, make sure you've set up your AXIS2_HOME class paths.
Sometimes it stops working for me too, and then I have to go and reinstall everything. Don't bother making bug reports to Eclipse or Apache, they are always closed as "WORKSFORME".
Steps to produce code from your wsdl:
Create a dynamic web project.
Create your wsdl file.
Right-click on your wsdl file, select Web Services -> Generate Java Bean Skeleton
Click Finish
The Axis2 libraries, facets, and generated code will be added to your project automagically, and there will be no compilation problems.
I had the same problem. I believe maven folder structure is causing it. I created a new project without maven and it worked. Added maven later. Also check source folders at "Java Build Path". If it is missing you will need to add it.
I was facing the same trouble but now it has been solved. The problem is if you have a method that 'THROWS SOME KIND OF EXCEPTION', then it will cause the problem. Hence instead of throwing the error, try using try-catch block statement.