function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
anagramanagram 

getting "org.xml.sax.SAXParseException: no document element" on old Session ID

This is odd. I'm doing some development and have been keeping around old session IDs to test with so I don't have to log in each time my program runs.

Normally when a session is no longer good I get fault code 1112 ("missing or invalid session ID") and sometimes 1005 ("session ID required in cookie"). This makes sense.

Recently, however, I got fault code 0 with this fault string:
org.xml.sax.SAXParseException: no document element

The session ID wasn't even that old, but I can't be sure it wasn't expired. Logging in again and getting a new session ID fixes the problem immediately. This is no big deal except that I wonder if it indicates I am doing something wrong.

Using XMLRPC, API 2.0. Below is the query that causes the fault. [ and ] replaces lt and gt for readability. Also below is the Session ID that causes the fault.

What's going on?!?! Thanks,
Nicholas

"lknQI2PFG7gpqXXvfNAFbpwzrqh38mtHRevIhWIYXnKFNYP.XR7zJqIeFqSJuZU0XNIqoIq22NVbTTlgQGSKufbtzKggVlhL"

[?xml version="1.0" encoding="UTF-8" ?]
[methodCall]
[methodName]sfdc.query[/methodName]
[params]
[param]
[value]
[struct]
[member]
[name]version[/name]
[value][string]2.0[/string][/value]
[/member]
[member]
[name]type[/name]
[value]account[/value]
[/member]
[member]
[name]scope[/name]
[value]filter[/value]
[/member]
[member]
[name]filter[/name]
[value]
[array]
[value]
[struct]
[member]
[name]field[/name]
[value]ownerID[/value]
[/member]
[member]
[name]value[/name]
[value]00530000000c7kx[/value]
[/member]
[member]
[name]operator[/name]
[value]equals[/value]
[/member]
[/struct]
[/value]
[/array]
[/value]
[/member]
[member]
[name]select[/name]
[value]
[array]
[value]id[/value]
[value]name[/value]
[/array]
[/value]
[/member]
[/struct]
[/value]
[/param]
[/params]
[/methodCall]
DevAngelDevAngel

Hi anagram,

That is an odd exception.  Is there more stack trace that's returned or is it just the one line in the subject of your post?

Did you remove the sessionID from the xml-rpc message that you posted?  Do you no longer get the 1112 and 1005, or do you get all three exceptions in random?

I will see if I can duplicate this.

DevAngelDevAngel

Hi anagram,

Can't duplicate the error.  What developer environment are you in?

anagramanagram
Hi Dave-

The old session ID no longer gives me the error. It now gives me the usual fault code for an expired session. But this one does now:
"azbkqjceUA6mA5V2HWx8xgW9uP1GZBzzmWDvK40JK6C7vab1bamQcys_tuzwiUYXL.4NYZ3hSuYPWqNGuOYoCvbtzKggVlhL"

I'm developing an application in C++ and creating my own XMLRPC queries. There is no other information returned with the fault response. An example is below.

In response to your other posting, I'm sending the session id as a cookie with the XMLRPC query. Also, once I start getting this exception for a give session ID, I never get the normal fault codes.

Also, I get the same exception on other queries, not just the one in my first post.

Thanks!
-Nicholas

[?xml version="1.0" encoding="UTF-8" ?]
[methodResponse]
[fault]
[value]
[struct]
[member]
[name]faultString[/name]
[value]org.xml.sax.SAXParseException: no document element[/value]
[/member]
[member]
[name]faultCode[/name]
[value][int]0[/int][/value]
[/member]
[/struct]
[/value]
[/fault]
[/methodResponse]
DevAngelDevAngel

Hi anagram,

Can you include the request in the same way you posted the response?

anagramanagram
Hi Dave-
Exactly the same as the original request in my original posting. Also, it does not seem to matter what kind of request I make, though I may be malformatting all of them in the same way. Once I get this exception with a session ID, I keep getting it.

Nicholas
DevAngelDevAngel

HI anagram,

Ok, dumb question.  What would be helpful is to capture the request just prior to posting it accross the wire and capturing the response just prior to it being processed by your app.  I'm talking raw xml soap messages.

You can capture these with various tools.  I use tcpMon from the Apache Axis project, but I think there is a HTTPMon and a TCPIPMon available from pockSoap.  These work like a proxy allowing the logging of the messages at the transport level.

It's very curious that the sax parser can't find the "document" part of you old sessionID request and we really don't know what that looks like unless we capture it.

anagramanagram
Hi Dave-
Found the TcpTrace tool. Very cool, thanks! Here are the results. The only thing changed is the lt and gt substitution for [ and ]. All other formatting is unchanged.

Hope this is what you were looking for. Thanks,
Nicholas

----------------------

The request:

POST /servlet/servlet.Api HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: localhost:8080
Content-Length: 842
Cache-Control: no-cache
Cookie: sid=kU0GQsr5n2ql9YajbN53BegbAGbPjCSWMk0nbRCNq2KFcfMN3VxJEvJ.K8enMeCtm8ccIUVut3FYw7XSHxn5BvbtzKggVlhL

[?xml version="1.0" encoding="UTF-8" ?]
[methodCall]
[methodName]sfdc.query[/methodName]
[params]
[param]
[value]
[struct]
[member]
[name]version[/name]
[value]
[string]2.0[/string]
[/value]
[/member]
[member]
[name]type[/name]
[value]account[/value]
[/member]
[member]
[name]scope[/name]
[value]filter[/value]
[/member]
[member]
[name]filter[/name]
[value]
[array]
[value]
[struct]
[member]
[name]field[/name]
[value]ownerID[/value]
[/member]
[member]
[name]value[/name]
[value]00530000000c7kx[/value]
[/member]
[member]
[name]operator[/name]
[value]equals[/value]
[/member]
[/struct]
[/value]
[/array]
[/value]
[/member]
[member]
[name]select[/name]
[value]
[array]
[value]id[/value]
[value]name[/value]
[/array]
[/value]
[/member]
[/struct]
[/value]
[/param]
[/params]
[/methodCall]


------------------------
The response:

HTTP/1.1 200 OK
Server: Resin/2.1.s030924
Cache-Control: private
Set-Cookie: sid=Tcjk6day83SHlD9Hidxp4iQVieMQdzXUTF6C5R3kc61mehNuWsT8zoblas.UB8n3Nup0UNXBACOOW3brM5mSovbtzKggVlhL; path=/
Content-Type: text/xml; charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 11 Dec 2003 19:10:16 GMT

123
[?xml version="1.0" encoding="UTF-8" ?][methodResponse][fault][value][struct][member][name]faultString[/name][value]org.xml.sax.SAXParseException: no document element[/value][/member][member][name]faultCode[/name][value][int]0[/int][/value][/member][/struct][/value][/fault][/methodResponse]
0
DevAngelDevAngel

Hi anagram,

The only thing that I could recommend is to include the sesionID in the message as well as the http header.  I know it seems redundant, but that is the recommended implementation.   Do that and let me know if you can then reproduce it.

You would use it like the version parameter:

[member]
 [name]
  session_id
 [/name]
 [value]
  [string]
   (SESSION ID TRUNCATED)q22NVbTTlgQGSKufbtzKggVlhL
  [/string]
 [/value]
[/member]
[member]
 [name]
  version
 [/name]
 [value]
  [string]
   2.0
  [/string]
 [/value]
[/member]

anagramanagram
Hi Dave-

Hmm, the 2.0 api docs don't seem to mention putting the session_id in like this. I tried as you suggested and got the same results, though.

Now that I've had some more experience with this the pattern is a tiny bit more clear:

I log in and get a session ID.
I re-use this session ID many times on queries, inserts, and updates during testing.
At some point, I start getting the SAX exception.
If I log in again and get a new session ID, the new one functions properly.
The old session ID continues to give the SAX exception for a while.
Eventually the old session ID simply gives a normal 1112 fault after it has expired.

FYI, this session ID is now causing the exception:
"a6cVDo1hXs2txEMJZx5k._gQHlN8FirW10ac6hzuw3FI__8bFNfOrsvf6GIFBWlg_PupU6QyD78NTXpD7UnwBfbtzKggVlhL"

Maybe you can try a query somehow with this session ID and see what happens?

Thanks for your quick followups!
Nicholas
DevAngelDevAngel

Hi anagram,

Nope, I get the 1005 error.

anagramanagram
Well it's a time-sensitive thing, as I mentioned. I now get the normal error response with that session ID (1112, not 1005, though). Might there be some way I can test this with another client of some sort? Something I can just drop the session ID into when the problem happens so I can see right away if the client makes a difference?

Thanks,
Nicholas
DevAngelDevAngel

Hi anagram,

I might be able to coble together a simple vb executable to do the trick.  You would just fire it up and past the session id into a text box and then click a button I think.

Can you run a vb app in your environment or do you need a runnable jar file?

anagramanagram
Hi Dave-
Well I don't love VB :-) but it would work. I have VB installed as part of visual studio if that's what you mean.

Thanks a million! I could watch the transactions from the VB program and from my program through tcpTrace and hopefully find something.

- Nicholas
DevAngelDevAngel

Hi anagram,

I'll clean up my tester program and send it to you tomorrow around noon PST.

anagramanagram
Hi Dave-
Still having problems. Would be great to have your tester program when you get a chance. Thanks!

Nicholas
DevAngelDevAngel

Hi anagram,

Sorry for the delayed response.  Attached is a vb app that wil prompt for a user name and password, and optionally, a session id and version number.  When you hit that strange session id error, copy the session id that is bad, fire up the vb app, enter username and password, paste the session id and optionally change the version number.  This will log in using xml rpc and get the correct url.  It will then change the session id to the pasted id and run a query to return all the contacts owned by the logged in user.  Running it in the visual studio environment will provide debug information.

Download the attached file and rename for .zp to .zip, this unzip to the location of your choice.

 

anagramanagram
Hi Dave-
Thanks for passing this on. It was a great help. After looking more closely at the differenes between the two requests, I found the problem, though I definitely don't understand it.

My program was including the header
Content-type: application/x-www-form-urlencoded
along with the request. Removing this header solves the problem.

Good for my purposes, BUT, it is still not clear why this happens. It is strange that all transactions with a new session id work perfectly with this header initially. After apparently one hour, like clockwork, the SAX exception starts happening. Removing the content type header fixes the problem.

I checked working and nonworking outgoing requests with tcpdump (both with the content type header, separated by an hour) and didn't find any differences. So I'm fairly sure that nothing is changing on my end and I'm guessing something happens on the server after an hour.

If you have any ideas it would satisfy my curiosity :-) Thanks again for your help!

Nicholas
adamgadamg

Hmm.  What XML-RPC client are you using?  (I assume its Apache, but if get a few more details we might be able lob this over to development to explore.)

anagramanagram
I've developed my own "client" that is built into my software. However, the client doesn't appear to matter. With the vb demo client that Dave provided if I add the line:

xmlhttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded"

to the Function postURL() in the xmlrpc module then the same thing happens after 1 hour using the same sessionid.

Best regards,
Nicholas
DevAngelDevAngel

Hi anagram,

Why do you add that http header?  Shouldn't it be text/xml or something like that?

anagramanagram
Hi Dave-
Yeah, I should have mentioned that the header was added by mistake. I adopted some code used to post urlencoded data and never removed the header.

I'd change it to text/xml or something more suitable except that I fear it would break something else :-) Any idea why that header would cause the SAX parse exception?

Nicholas
DevAngelDevAngel

Hi anagram,

No, I don't know where to start with this issue.  All I can figure is that maybe the header is affecting the "context" of the session id.  But I really don't think that is what's going on.  Can you expose the header up to the level of when you make the soap call?  Maybe like a wrapper that takes an extra argument that would be used to specify the correct header value for sfdc.

Do you know specifically what the particular header is used for?  Seems like more of a get type of header than a post.

anagramanagram
Hi Dave-
I think this is clear, but the Content-type header is used with POST requests to specify the content of the POSTed data. It can be any mime type, but is most often x-form-urlencoded to specify data from a web form. In the salesforce case, that is clearly not the correct format.

It makes sense that the receiving end is seeing this header and trying to interpret the POSTed data differently. This could easily lead to the error I'm seeing. HOWEVER, it is odd that this doesn't happen until the session ID is 1 hour old.

No matter, I feel quite confident that posting without the content-type header works perfectly and my problem is solved. Just thought I'd provide the solution in case it was of concern to the salesforce team.

Thanks,
Nicholas