24.3.05

Calling C/C++ gSOAP Web Services from JDeveloper

gSOAP is publicly developed C/C++ SOAP framework for Web Services client and server development.

Here is some loggin information trying to get Java -> C++ (via Web Services) to work together.

gSOAP distribution does not have ready made *.dlls or *.lib libraries for direct compilation. I had already Microsoft Visual C++ 6, which was just perfect environment for compiling the gSOAP basic *.dll's and sample C/C++ application. I tought I start the mini-project with the calculator samples mentioned in the manual. Generated the needed source code (*.cpp and *.h) + resource files using soapcpp2.exe.

Ok. after little bit of tweaking I got the first calc.exe to run as Web Service. Remember to add the "soap_set_namespaces(&soap, namespaces);" line after "soap_init(&soap)" in the C++ code. This will result the response message having all the needed namespaces and avoiding "SOAP version mismatch or invalid SOAP message" -error. Also noticeable was that the simple samples in manual did not work "as is" but the multi-threaded (with pooling) seems to work just fine, so that code base was used to serve the Web Service calls.

Imported the generated WSDL to the JDeveloper (9.0.5.2) and generated the Java sample code. Trying to run the Web Service stub results in following error message: "Method 'ns1:add' not implemented: method name or namespace not recognized".

=> The problem was that the sample Calc.cpp had some odd namespace definitions. After I copied the namespace definitions form Calculator.nsmap the Web Service started working.

After this the TCP packet monitor showed that Web Service returns the right answer, but Java deserializer returns an exception at Java side:

[SOAPException: faultCode=SOAP-ENV:Client; msg=No Deserializer found to deserialize a ':result' using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'.; targetException=java.lang.IllegalArgumentException: No Deserializer found to deserialize a ':result' using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'.]
at org.apache.soap.SOAPException.<init>(SOAPException.java:78)
at org.apache.soap.rpc.Call.invoke(Call.java:308)
at oracle.emp.kaukovuo.ws.mypackage.CalculatorStub.add(CalculatorStub.java:79)
at oracle.emp.kaukovuo.ws.mypackage.CalculatorStub.main(CalculatorStub.java:36)
Process exited with exit code 0.


Looks like the result -element should be data typed (the same kind of problems as with Microsoft SOAP Toolkit). This is easily worked around with J2EE Web Services by adding web.xml initialization parameter "accept-untyped-request" to "true". How is this done in Java client environment when receiving response?

The response to the question lies in gSOAP manual chapter: "8.1.5 XSD Type Encoding Considerations".

The most important thing is to compile the header file with "-t" option. This generates code to send typed messages (with the xsi:type attribute).
For fast development you should take a look at the *.xml files that soapcpp2 compiler generates. These will reflect the requests and responses that the SOAP client/server will receive. In the first phase you don't need to get everything running to test.