History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: XFIRE-505
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Critical Critical
Assignee: Tomasz Sztelak
Reporter: Michael Vorburger
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
XFire

Should resolve w3.org etc. references without Internet access to

Created: 29/Jun/06 11:13 AM   Updated: 12/Aug/06 07:30 AM
Component/s: Core
Affects Version/s: 1.1.2
Fix Version/s: 1.2

Time Tracking:
Not Specified

File Attachments: 1. Text File XFIRE-505-Exception.txt (4 kb)


Testcase included: yes


 Description  « Hide
As discussed on the "Looking for xsd (schema) on local file system, instead on the web ?" thread on user list (http://www.nabble.com/%3A--Looking-for-xsd-%28schema%29-on-local-file-system%2C-instead-on-the-web---tf1801518.html#a4910149), XFire (StAX actually) currently requires an open Internet connection to consume web services.

This is a likely a problem in many production environments as not allowing outgoing internet is very common (that's why I suggest this is Critical), as well as not allowing to develop offline on e.g. a laptop (running provider on localhost, consuming localhost) which is certainly not critical but (to me) still handy.

On http://www.nabble.com/%3A--Looking-for-xsd-%28schema%29-on-local-file-system%2C-instead-on-the-web---tf1801518.html#a4910149 there is a suggested work-around.



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Michael Vorburger - 29/Jun/06 11:26 AM
I was thinking about a testcase for this... it's easy to reproduce - pull the network plug and run any XFire client, but you can't pull the plug in automated unit tests... or can you? How could you do simulate an 'ifdown' from a Java Test Case? (If it's worth anything, I am going to attach a BookServerTestCase which when I pull the plug causes this; when the plug is in there is another issue, but that should be easy to solve for committers.)

Whatever StAX is looking for (Schema for http://schemas.xmlsoap.org/soap/envelope/, xmlns:xsd="http://www.w3.org/2001/XMLSchema or http://www.w3.org/2001/XMLSchema-instance NS? I don't entirely understand, because validation is off by default isn't it?) should probably be included as a resource in the XFire (Core) JAR. Other frameworks included e.g. their DTD in their JAR and always use that fetching of a remote one.

By the way... not sure what all to include. E.g. if you use WSSecurity, more stuff is probably going to be fetched, so that all would have to be included I guess? Or somehow make it not go trying get any of this.

Will also attach the full error (stack trace) that occurs under this condition; makes it easier to find this.


Michael Vorburger - 29/Jun/06 11:27 AM
Stack Trace.

Michael Vorburger - 29/Jun/06 03:52 PM
Whoa ... I (and referenced mailing list discussion) got this all wrong .. I think. After more debugging:

The good news is that using XFire client to access e.g. that book example service positively does work offline on e.g. a laptop not connected to the Internet or any local network at all, at least in 1.1.2 (have not tested previous).

The bad news is that the error handling for HTTP errors, e.g. miss-spelt service URLs that lead to an HTTP 404 is quite confusing, and probably the cause of what I was experiencing, and presumably 'sol myr' who initially posted the issue to the list. I did some tests, and here is what happens if you access a miss-spelt service URLs (with a correct/existing host/port) in different combinations:

  • on Tomcat 5.5, with no Internet: XFireFault: Unexpected close tag </body>; expected </HR>.
  • on Jetty, with no Internet: XFireFault: www.w3.org
  • on Tomcat 5.5, with Internet: XFireFault: Unexpected close tag </body>; expected </HR>.
  • on Jetty, with Internet: XFireFault: There must be a method name element.

Tomcat's HTML 404 error page is not valid XHTML; XFire asks StAX to parse it, which complains - Internet or not. However under Jetty (via XFireHttpServer-based test case) and most likely other servlet containers that return valid XHTML including DOCTYPE in case of 404-like errors, as well as Tomcat when returning a page like XFire's "Services:" page in XHTML, e.g. because a */services/ URI, without actually naming a service, make StAX retrieve the http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd from the <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">, leading to the XFireFault: www.w3.org / Caused by: java.net.UnknownHostException: www.w3.org.

So it actually does all make perfect sense: XFire does not retrieve "retrieve some of the standard WS schemas", only the XHTML DTD in case of error pages; I actually verified this with a custom XMLResolver as suggested by 'sol myr' in the "work around" (which now doesn't look like it's the needed approach).

Wouldn't it be much clearer and avoid this confusion in the future if the exception would be something like XFireFault: Server returned 404 for [URI] in such cases? I do think including the URI is important by the way, because you can go look it up in the browser then, and figure out what it has to be.

So I guess if an HTTP server returns a 404 or 500 or something else than 200, XFire client should never attempt to parse the HTTP body of the response as XML... or is this valid in SOAP? How does it work for SOAP Faults, is that still HTTP #200, or is that a #500? I found some code in SimpleMessageSender and assume there is something similar in the CommonsHttpMessageSender, but it should probably be changed to throw a more specific error as suggested above, and not parse XML.

Actually, coming to think of it, even if the HTTP return code is 200, it could of course well be invalid XML, e.g. an HTML page, or binary, if you "miss-spelt" the URL. While above is being addressed, additional better error handling in that case, something like XFireFault: Server returned invalid SOAP response for {URI} instead of e.g. XFireFault: www.w3.org, Caused by: java.net.UnknownHostException: www.w3.org would make sense, too?

PS: How to change JIRA issue summary & priority?

PPS: Having said all this... I wonder if it is possible for a valid SOAP request / response to contain e.g. a schemaLocation, causing XFire / StAX to attempt to fetch a schema after all (again, not what happened here; just thinking aloud). Is that possible? Probably not in the outgoing SOAP request created by XFire.. but could it be in the incoming response? Completely disable schema validation by default in StAX so this doesn't cause problems in Internet-disconnected environments - IFF this is a potential issue at all?


Dan Diephouse - 30/Jun/06 09:24 AM
I think we definitely can add some other resolver. As you said, StAX is responsible for this somehow, but I don't know how to turn it off offhand. I agree it should be off by default and we'll have to do this for 1.2.

Tomasz Sztelak - 05/Jul/06 03:15 AM
I added some code to check http error code, but no all cases can be handled this way. Soap fault ( very valid soap message ) is send with 500 error code, so we cannot find out if this a real server error or just fault returned.
( Dan, is this requried by any spec to send faults with server error code http error ? )

Michael Vorburger - 05/Jul/06 04:25 AM
Hm... I see. I guess I would have done some "heuristics", e.g. along those lines: IFF the HTTP return code is NOT 200 or 500, then abort with an Exception like XFireFault: Server returned 404 for [URI]. Else, so if HTTP return code IS 200 or 500, attempt to parse XML and interpret as SOAP. If that fails "due to XML parsing or something similar" [I am thinking catch(TheXMLParsingSuperclassException), not catch(Exception)] then abort with an Exception like XFireFault: Server returned invalid XML/SOAP response for [URI]. What do you think?

Is your JIRA and Subversion linked - i.e. can I see the diff/patch (curiosity, mainly) and comment/help?

BTW, on my PPS: I meanwhile realized, after discussion with a colleague, that schema validation ("add some other resolver") is an entirely different topic... nothing gets validated here, StAx does not, can not, validate the incoming or outgoing SOAP just like that (unless you already have dedicated code for that that I haven't seen?). But you could validate the incoming and outgoing because you do have the schema in the WSDL (the schemaLocation that I first wrote probably is never there). That could be an interesting additional new In- and OutHandler (if you don't have it already) that some people may be interested in using and (manually) adding to the chain. I wouldn't include it by default though, for speed. Again that's a completly separate story from this, and maybe a new possible Enhancement? (Of course, the WSDL could reference a schema via URL, in which case you could be back to what started this discussion, but this time the real meaning of that error, I mean not being able to download that schema when validating... you could probably offer to configure that Handler to use local copies, then.)


Tomasz Sztelak - 05/Jul/06 04:56 AM
Currently i'm doing only, lets say , research, so there is not much to show (only some hooks ). But i would like to have all error code handled in one way ( all code >= 400 + 301 which is used by http client for error 404 in some cases ), thats why i'm trying to solve error 500 problem in case of regular soap faults first.

I'm also adding ability to access XMLInputFactory properities via config/api, so you can disable e.g supportDTD, what may help solving one of the problem you reported.


Tomasz Sztelak - 06/Jul/06 01:24 PM
if you want to comment :
I commited folowing code
// IF 0 is return then no error occour, in other way return error code

public int hasError(){
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
int statusCode = postMethod.getStatusCode();
// Code 500 is send with every fault so we can't treat it as server exception.
// http client somehow converts 404 errr code returned on services list ( http://server/app/services ) to 301
if( statusCode !=500 && ( ( statusCode >= 400 && statusCode < 600 ) || statusCode == 301 )){ return statusCode; }
return 0;
}

So all error codes except 500 willbe handled and message won't be parserd. As you see i exclued error code 500 becasue XFire send this code with every SOAP fault, but when Dan will be back, i plan to talk to him about this, so we can handle this error code also.
Error code 301 is added here, becasue our service list return html page with error code 404 which is converter by http client to 301

You can give it a try, if this want solve every problem you reported, let me know, then i'll commit acces to stax properties code.


Michael Vorburger - 10/Jul/06 07:13 AM
I see the your in the condition, but personally I think I would have treated this the other way around, with a condition like:

if( statusCode !=500 && statusCode != 200 ){

or maybe

if( statusCode !=500 && statusCode >= 300 ){

You probably think that's too risky? I'd argue that within that code you get e.g. an 300 that's still an indication of a problem, as any e.g. redirects would have to be resolved by the HTTP client library (JDK or commons) and that code can't do anything about it, so has to consider it an error? That's just my thinking...

How do you handle if your hasError() returns 0 but there is an XML/SOAP Parsing issue? There is one particular case where I believe this is quite likely to happen: A #500 code due to a "real" internal server error, that is not returned as a SOAP Fault with proper XML in the Body, but as a Servlet Container (Exception Stacktracing showing) HTML Error page. That's why I would, even if hasError() == 0 do something like: catch(TheXMLParsingSuperclassException) [not catch(Exception)] then abort with an Exception like XFireFault: Server returned invalid XML/SOAP response for [URI]. (And log the received response (body) if in DEBUG, and/or maybe better include it in a special Exception, for the caller to decide.)

Actually, maybe doing anything based on the HTTP response code is not very safe... how about ONLY doing the idea in the paragraph above, that is as long as there is a valid/parsable SOAP message in the response, handle it, otherwise throw a clearer Exception than is the case today?


Dan Diephouse - 11/Aug/06 01:04 PM
I'm closing this as I don't think its actually an issue (feel free to reoopen if it is). I know that we do require you to be online for a build at the moment which sucks, but getting the a list of services does work regardless - which I believe you've confirmed in this thread Michael.

Michael Vorburger - 12/Aug/06 07:30 AM
Certainly. I saw some code from Tomasz in the 1.2 in SVN that should address this. (I actually haven't really had a chance yet to check it out though.)

PS: The Issue title is very misleading now, this isn't at all about being online anymore, but I was unable (or too dumb) to change the title... it should probably be something like "Improved error handling for HTTP errors like 404 etc."