Error when calling .Net Web Service from Blackberry - web-services

I'm calling a .Net Web Service which takes a complex type as a parameter (using KSoap2). I've done this before successfully so I decided to just copy my old code and paste it into a new method, replacing some code with code relevant to the current web service of course.
The only real difference I can see is that the URL to the new web service's .asmx is different.
The thing is I keep getting the following error:
(I get the following when SoapEnvelope.VER11)
org.xmlpull.v1.XmlPullParserException: expected: END_TAG {http://schemas.xmlsoap.org/soap/envelope/}Body (position:END_TAG </{http://schemas.xmlsoap.org/soap/envelope/}soap:Fault>#1:338 in java.io.InputStreamReader#199cb474)
(And the following when SoapEnvelope.VER12)
org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://www.w3.org/2001/12/soap-envelope}Envelope (position:START_TAG <{http://schemas.xmlsoap.org/soap/envelope/}soap:Envelope>#1:207 in java.io.InputStreamReader#5b209e72
Why would the error message change like this depending on the version of SOAP I use?
I also tried printing out my envelope with HttpTransport.requestDump and I get the following:
xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<postMessage xmlns="http://www.magnatech.com/" id="o0" c:root="1">
<myMessage i:type="n0:Message" xmlns:n0="http://www.magnatech.com/">
<messageContent i:type="d:string">HEY</messageContent>
<userName i:type="d:string">TEST USERNAME</userName>
<agentName i:type="d:string">TEST AGENT NAME</agentName>
<userID i:type="d:string">0</userID>
<agentID i:type="d:string">0</agentID>
<fromAgent i:type="d:string">false</fromAgent>
<messageID i:type="d:string"></messageID>
<accountNumber i:type="d:string">TEST ACCOUNT</accountNumber>
</myMessage>
</postMessage>
</v:Body>
Which looks fine, I actually did the same thing with the envelope from my other "WORKING" web service call and they are the same, except for the element names of course.
And finally, here is the output from HttpTransport.responseDump:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Could not deserialize Soap message</faultstring></soap:Fault></soap:Body></soap:Envelope>
So obviously there is something wrong with the envelope as I'm sending it, yet I see nothing wrong with it.
What could be the problem? I've tried everything possible and am running out of ideas.
Any help at all will be greatly appreciated.
Thanks

Related

Web Service Error 400 - Bad Request

I have a perplexing issue. I have Web Service A (henceforth WSA), a 3.5 .Net WCF, which I have added a call to Web Service B (henceforth WSB) which is a 3.5 .Net ASMX. When running WSA in the client (SOAPUI or WCFStorm), the WSB call times out per the client timeout setting.
In the VS event viewer I can see that the call to WSB immediately throws two error 400s:
Exception thrown: 'System.Net.WebException' in System.dll ("The remote
server returned an error: (400) Bad Request."). Exception thrown:
'System.Net.WebException' in System.dll ("The remote server returned
an error: (400) Bad Request.")
No reason is given. What is just as puzzling to me is the error doesn't go to my catch. When I debug and I hit the line of code that calls WSB, it's like a reset. No further code gets executed and no error is thrown by my WSA.
If I call WSB directly, it works. So nothing is wrong with WSB. At suggestion of a coworker, I took the code specific to my change and put it in a stand-alone service. I literally C&P the code and configs setting specific to me and adjust namespaces and class names. Lo and behold it works. My stand-alone web service called WSB just fine and get the data I expect.
A coworker and I checked the logs (IIS log for the service and the HTTPERR log) on the IIS server that WSB resides on to see if there was any mention of the 400 error. We found none.
So we are kind of perplexed at this point. The only thing we can think of is perhaps something in the web config might be interfering but have no idea what it could be.
If you have any suggestions of where else to look that would be helpful.
And it would be nice to know why it isn't falling into my error handler.
Thanks.
Update: It was requested I add config and code. I don't think it will help honestly and it is pretty straightforward. I can't put the real code due to company reasons but it is basically this:
In web config:
<configuration>
<appSettings>
<add key="endpointUrl" value = "someurl" />
</appSettings>
.
.
.
<applicationSettings>
<MyService.Properties.Settings>
<setting name="MyService_TheirService"
serializeAs="String">
<value>someurl</value>
</setting>
</MyService.Properties.Settings>
</applicationSettings>
Even though the data is super small I did try making large reader settings and such:
<binding name="CustomHtttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="01:50:00" openTimeout="01:50:00" sendTimeout="01:50:00" receiveTimeout="01:50:00" >
<readerQuotas maxDepth="128"
maxStringContentLength="8388608"
maxArrayLength="2147483646"
maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
</binding>
Code:
using MyService.TheirService
.
.
.
var theirURL = ConfigurationManager.AppSettings["endpointUrl"];
var oSvc = new TheirServiceObject
{
Url = theirURL
};
int numberIneed = oSvc.SomeMethod();
That last line is where it throws the 400.
UPDATE 2:
A colleague show me how to use Fiddler. And I can now see that the request to WSB is absolute garbage.
xڭ s 6 mr!!u \ .3 5'3 G QOH>Iп kX M3 ~vY ) X e Z
w ~ :jv -ݴwڽHb Yqv A :(Q Z; >9W O0g 6 .ɖVlU Ţ 8Z
< ( t eSv U]r R $N \
Some odd encoding? At least it's another clue.
Wanted to let you know this problem was solved. Another Dev that had worked on this service before but no longer just happened to walk by and I said "Hey! Look at this!"
They saw the garbage request data and said "That looks like compression. Look up compression in the project."
Turn out there was a custom compression component that was compressing the outgoing data of the service and you needed to add 2 lines of code to decompress. After adding those lines to the top of my method everything immediately worked.
The lesson here is if your project is doing some weird stuff that defies reason, try and find as many people as you can that worked on it before even if they aren't working on it anymore.

Remove outbound unused namespaces from soap body message

I am using CXF JAXWS Client for retrieving some information from an external web services. So, basically, we have .xsd and .wsdl files from the external and try to implement our ws consumer by generating the client stubs using cxf-codegen-plugin. We cannot change the .xsd and .wsdl files. Everything works fine, we are able to send and retrieve soap messges from the external services.
However, when I look into the soap request message from the log, I find a lot of unused namespaces in the soap (body) message sent from our ws client.
Below is an example
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:aheaderns="http://xxx.xxx.xxx.xxx/header.xsd">
<soap:Header>
...
</soap:Header>
<soap:Body>
<ns7:requestQuery xmlns:ns15="http://xxx.xxx.xxx.xxx/AAA" xmlns:ns14="http://xxx.xxx.xxx.xxx/BBB" xmlns:ns13="http://xxx.xxx.xxx.xxx/DDD" xmlns:ns12="http://xxx.xxx.xxx.xxx/CCC" xmlns:ns11="http://xxx.xxx.xxx.xxx/EEE" xmlns:ns10="http://xxx.xxx.xxx.xxx/FFF" xmlns:ns9="http://xxx.xxx.xxx.xxx/GGG" xmlns:ns8="http://xxx.xxx.xxx.xxx/HHH" xmlns:ns7="http://xxx.xxx.xxx.xxx/III" xmlns:ns6="http://xxx.xxx.xxx.xxx/JJJ" xmlns:ns5="http://xxx.xxx.xxx.xxx/KKK">
<ns7:sample>
<ns7:type>A</ns7:type>
<ns7:ref>1</ns7:ref>
</ns7:sample>
</ns7:requestQuery>
</soap:Body>
Is there any way to remove the unused namespaces from the outbound soap message sending from the client?
You could move your client proxy classes to the same package and map it to the proposed namespace specified in the wsdl.
Put this code into the package-info.java class:
#XmlSchema(xmlns = { #XmlNs(prefix = "ns1", namespaceURI = "http://xxx.xxx.xxx") },
namespace = "http://xxx.xxx.xxx")
package clinet.sample.proxy;
import javax.xml.bind.annotation.XmlNs;
Hope this helps.
After digging into this problem for quite sometime, I found the solution. However, I think my solution is not to solve the problem at the root cause but it works for now.
Basically, I use XSLTOutInterceptor from CXF to apply the XSL to the out message. However, the default PRE_STEAM phase is not working for me. Then, I decide to extend the XSLTOutInterceptor so as to change its PHASE to WRITE. So that, the unused namespaces will be removed during the writing of the protocol message before sending it out.
The XSL I use is from how to remove unused namespaces from source xml
By the way, I still have no idea why those unused namespaces have been generated. If anyone could give me a suggestion, I would appreciate it.
Thanks :)

gSOAP empty answer

I'm writing a SOAP client. I'm using gSOAP version 2.7.17 and I have to stick to that version as the server is using this one and I cannot modify it as it is already running in the field.
When I do my SOAP call, I always receive empty answer! However, when I sniff the network, the XML answer seems correct:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:Supervisor="urn:Supervisor"
xmlns:ActiveLogin="urn:ActiveLogin" xmlns:TechLogin="urn:TechLogin"
xmlns:UMSLogin="urn:UMSLogin">
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<unitCallResponse>
<szServerName>UMS_DEV_LANCC2 (2)</szServerName>
<dResponse>cUNITRETURNCODE_RESTARTIMMEDIATE</dResponse>
<dDetail>cBla</dDetail>
</unitCallResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here is a simplified code snippet about how I perform the SOAP call with the proxy generated with soapcpp2:
UMSLogin::unitCallResponse response; // Response from SOAP
UMSLogin::UMSLoginProxy* m_soapProxy = // The SOAP proxy
new UMSLogin::UMSLoginProxy(SOAP_IO_KEEPALIVE, SOAP_IO_KEEPALIVE);
callRes = m_soapProxy->unitCall(m_eUnitType, serial, m_dInterfaceVersion,
xl2CallTypeToUmsLoginCallType(m_pSoapEndPoint->getCallType()),
xl2CommTypeToUmsLoginCommType(m_pSoapEndPoint->getComType()),
response);
logDebug(LOG_COM_DEVICE, "SOAP call done to %s, SOAP code %i, central code %i",
response.szServerName.c_str(), callRes, response.dResponse);
m_soapProxy->soap_close_socket();
m_soapProxy->destroy();
delete m_soapProxy;
The actual output:
SOAP call done to , SOAP code 0, central code 0
When I expect
SOAP call done to UMS_DEV_LANCC2 (2), SOAP code 0, central code 5
/* 5 -> cUNITRETURNCODE_RESTARTIMMEDIATE */
There was an old implementation that was working previously, this must be working! Where am I wrong? Did anyone has already had this kind of problem? Any pointer is strongly appreciated!
EDIT:
Problem was "solved" by using an earlier version of SOAP (2.7.14) without changing a single line of code from the original version of my program. However, I have the feeling I miss something important again! I should probably tweak a little my header file giving the SOAP "definitions" to make things working ...
Looking at your code you declare response and then reference the elements of it as response.dResponse. This seems to imply that response is a struct rather than a pointer to a struct so after you call m_soapProxy->unitCall the version of response that you then report on hasn't changed, only the copy in m_soapProxy->unitCall will have changed.
I'd try tracing this call through in the debugger and see what is actually happening in m_soapProxy->unitCall. BTW is it you code or generated by GSOAP?

InstantiationException in web service client calling Web Service deployed to JBoss

I'm deploying a StatelessSessionBean annotated with #WebService to JBoss. I'm taking the WSDL generated by JBoss to generate client stubs. My problem is in calling a method which returns a list of objects. If the list is empty the call succeeds however if the list is not empty then I get the following exception:
com.sun.xml.ws.encoding.soap.DeserializationException: Failed to read a response: javax.xml.bind.UnmarshalException
- with linked exception:
[javax.xml.bind.UnmarshalException: Unable to create an instance of com.companyname.api.ws.DataItemType
- with linked exception:
[java.lang.InstantiationException]]
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:124)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)
at $Proxy34.getWorkflows(Unknown Source)
at com.companyname.api.SimpleClient.go(SimpleClient.java:48)
Searching the web led me to this discussion here: http://forums.java.net/jive/message.jspa?messageID=281780
However I have set the #XmlSeeAlso stuff correctly and it is present on the generated stub classes. I can confirm that the DataItemType class is abstract so it is not surprising that an attempt to instantiate it causes a problem. I'm not at all clear on why the DataItemType class is being instantiated at all (as it is abstract). This is the XML that is returned from the server (it looks about right to me):
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
<env:Header></env:Header>
<env:Body>
<ns2:getWorkflowsResponse xmlns:ns2="http://ws.api.companyname.com/">
<return>
<id>
<identifier>1</identifier>
<version>0</version>
</id>
<goal>ENROLL</goal>
<dataItemType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="DataItemTypeText">
<attributeName>email</attributeName>
<displayName>Email Address</displayName>
</dataItemType>
...
</return>
</ns2:getWorkflowsResponse>
</env:Body>
</env:Envelope>
Does anyone know what I'm doing wrong?
There were a number of issues with the generated WSDL (note that it wasn't a handcrafted one). There was nothing specific that I changed which indicated why this particular exception was thrown (or why, for example, there wasn't a failure when generating the incorrect WSDL).
Once I adjusted the annotations so that a valid WSDL was created then I had further issues which the JAX-WS versions I was using. I ended up upgrading the version used by JBoss which, in turn, led to me needing put the newer JAX-WS jars in my JRE endorsed directory.
I'm not going to detail what I did in any more detail as there was no specific thing that I did that addressed this problem. If anyone else sees it I would suggest being very specific in the annotations you use to generate your WSDL and taking a careful look at your WSDL.

Complex Object in JAX-WS is created empty

I'm testing JAX-WS to access the Oracle IRM web serviecs. I can get it to work just fine with AXIS so this isn't an Oracle problem.
What's happening is that I'm getting the following error when making the call:
Expected xsd:anyType - unknown type provided
If I look at the SOAP packet is sent I see that the owner tag is blank under JAX-WS:
<ns1:browseAccounts>
<owner/>
<accountType>All</accountType>
</ns1:browseAccounts>
The same piece under AXIS is this:
<owner xsi:type="ns1:LicenseServer"
xmlns=""
xmlns:ns1="http://www.sealedmedia.com/ls/server/schema">
<serverKey>#############</serverKey>
</owner>
Obviously the owner tag is not getting properly created, this is what I'm using to create that:
AccountServicesPort AA = ORI.getAccountServices();
LicenseServer LicSer = new LicenseServer();
LicSer.setServerKey("#######################");
List<Account> Acts = AA.browseAccounts(LicSer,AccountAccountType.ALL);
Is there some other process that I need to go through to create the object properly?
EDIT
I thought maybe running the LicenseServer creation through ObjectFactory would help. Unfortunately, it doesn't.
Despite the Oracle IRM documentation stating that BrowseAccounts accepts either a LicenseServer object or a Context object for the owner parameter it actually accepts an LicenseServer_ref.
EDIT
Further, I was running JAX-WS under JDK 1.6.0 which is a lower version than JDK 1.6.0_14. The new version supports XMLSeeAlso annotation which allowed JAX-WS to use the proper class for serialization.