Thanks for the info. I will look into it tomorrow when I am in the office. Chuck
From: Sergey Beryozkin Sent: 4/13/15, 8:59 PM To: [email protected] Subject: Re: Socket issues with 2.6.1 and JDK 7 Hi Thanks for this analysis. CXF 2.6.x is not supported any longer but CXF 2.7.x still is, It is a bit late so I only checked the trunk (CXF 3.1.0-SNAPSHOT), can you please check URLConnectionHttpConduit.getInputStream() ? It appears to be doing the right code In CXF 2.7.x this method is probably directly in HttpConduit... Besides that I guess WebClient can auto-close InputStream it reads. There's a property for it, "response.stream.auto.close". Or if you read InputStream directly then it needs to be closed manually Cheers, Sergey On 13/04/15 16:55, Canning, Charles wrote: > Hi, > > We are using the 2.6.1 WebClient for REST calls and we are running into > issues where the sockets try to connect to 0.0.0.0 (anywhere address) after > the client has been running for a while. After some analysis of the symptoms > and going through the source for the sun.net and cxf code, we believe it is > related to this Oracle document > > https://docs.oracle.com/javase/7/docs/technotes/guides/net/http-keepalive.html > > And around properly supporting 4xx/5xx status codes and the internal > keep-alive cache. > > Here is what I think is the relevant excerpt: > > What's new in Tiger? > > When the application encounters a HTTP 400 or 500 response, it may ignore the > IOException and then may issue another HTTP request. In this case, the > underlying TCP connection won't be Kept-Alive because the response body is > still there to be consumed, so the socket connection is not cleared, > therefore not available for reuse. What the application needs to do is call > HttpURLConnection.getErrorStream() after catching the IOException , read the > response body, then close the stream. However, some existing applications are > not doing this. As a result, they do not benefit from persistent connections. > To address this problem, we have introduced a workaround. > > The workaround involves buffering the response body if the response is >=400, > up to a certain amount and within a time limit, thus freeing up the > underlying socket connection for reuse. The rationale behind this is that > when the server responds with a >=400 error (client error or server error. > One example is "404: File Not Found" error), the server usually sends a small > response body to explain whom to contact and what to do to recover. > > Several new Sun implementation specific properties are introduced to help > clean up the connections after error response from the server. > > The major one is: > > sun.net.http.errorstream.enableBuffering=<boolean> > default: false > > With the above system property set to true (default is false), when the > response code is >=400, the HTTP handler will try to buffer the response > body. Thus freeing up the underlying socket connection for reuse. Thus, even > if the application doesn't call getErrorStream(), read the response body, and > then call close(), the underlying socket connection may still be kept-alive > and reused. > > The following two system properties provide further control to the error > stream buffering behavior: > > sun.net.http.errorstream.timeout=<int> in millisecond > default: 300 millisecond > > sun.net.http.errorstream.bufferSize=<int> in bytes > default: 4096 bytes > > What can you do to help with Keep-Alive? > > Do not abandon a connection by ignoring the response body. Doing so may > results in idle TCP connections. That needs to be garbage collected when they > are no longer referenced. > > If getInputStream() successfully returns, read the entire response body. > > When calling getInputStream() from HttpURLConnection, if an IOException > occurs, catch the exception and call getErrorStream() to get the response > body (if there is any). > > Reading the response body cleans up the connection even if you are not > interested in the response content itself. But if the response body is long > and you are not interested in the rest of it after seeing the beginning, you > can close the InputStream. But you need to be aware that more data could be > on its way. Thus the connection may not be cleared for reuse. > > Here's a code example that complies to the above recommendation: > > try { > URL a = new URL(args[0]); > URLConnection urlc = a.openConnection(); > is = conn.getInputStream(); > int ret = 0; > while ((ret = is.read(buf)) > 0) { > processBuf(buf); > } > // close the inputstream > is.close(); > } catch (IOException e) { > try { > respCode = ((HttpURLConnection)conn).getResponseCode(); > es = ((HttpURLConnection)conn).getErrorStream(); > int ret = 0; > // read the response body > while ((ret = es.read(buf)) > 0) { > processBuf(buf); > } > // close the errorstream > es.close(); > } catch(IOException ex) { > // deal with the exception > } > } > > > My question(s) are: > > > * Does CXF WebClient handle this? > * If so, which versions? > * Where is the code that handles this located > * Are users of WebClient supposed to manage this? > * Have you seen this error before? > > Any help/pointers would be greatly appreciated. > > Thanks, > Chuck >
