title: Spring Rest Template usage causes EOFException
body: <p>I'm receiving <code>java.io.EOFException</code>'s when using Spring REST template on Android.</p>
  
  <p>The stacktrace cause reads like this:</p>
  
  <pre><code>Caused by: java.io.EOFException
  at libcore.io.Streams.readAsciiLine(Streams.java:203)
  at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:560)
  at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:813)
  at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
  at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)
  at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:49)
  at org.springframework.http.client.SimpleClientHttpResponse.getStatusCode(SimpleClientHttpResponse.java:55)
  at org.springframework.http.client.BufferingClientHttpResponseWrapper.getStatusCode(BufferingClientHttpResponseWrapper.java:47)
  at com.company.util.LoggingClientHttpRequestInterceptor.intercept(LoggingClientHttpRequestInterceptor.java:33)
  at org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:81)
  at com.company.api.interceptor.AuthTokenInterceptor.intercept(AuthTokenInterceptor.java:51)
  at org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:81)
  at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:67)
  at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
  at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:63)
  at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:475)
  ... 14 more
  </code></pre>
  
  <p>Another similar stacktrace:</p>
  
  <pre><code>org.springframework.web.client.ResourceAccessException: I/O error: null; nested exception is java.io.EOFException
  at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:490)
  at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:438)
  at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:414)
  at com.company.api.ApiClient_.logLoginAttempt(ApiClient_.java:299)
  at com.company.security.CompanyAuthenticationService$2.onCreateCall(CompanyAuthenticationService.java:206)
  at com.company.api.SafeApiCall.doInBackground(SafeApiCall.java:49)
  at com.company.api.SafeApiCall.doInBackground(SafeApiCall.java:22)
  at android.os.AsyncTask$2.call(AsyncTask.java:287)
  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
  at java.lang.Thread.run(Thread.java:856)
  Caused by: java.io.EOFException
  at libcore.io.Streams.readAsciiLine(Streams.java:203)
  at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:560)
  at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:813)
  at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
  at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)
  at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:49)
  at org.springframework.http.client.SimpleClientHttpResponse.getStatusCode(SimpleClientHttpResponse.java:55)
  at org.springframework.http.client.BufferingClientHttpResponseWrapper.getStatusCode(BufferingClientHttpResponseWrapper.java:47)
  at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:46)
  at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:476)
  ... 13 more
  </code></pre>
  
  <p>This is all happening on Android 4.1.2, installed on my Xoom tablet.</p>
  
  <p>The problem appears and disappears. It's not triggered by long requests either. The server part is running on a machine within the local network. When I try to run the API Calls through <code>curl</code>, it works just fine.</p>
  
  <p><strong>AuthTokenInterceptor</strong>:</p>
  
  <pre><code>@Override
  public ClientHttpResponse intercept(HttpRequest request, byte[] data, ClientHttpRequestExecution execution) throws IOException {
      HttpHeaders headers = request.getHeaders();
      if (!StringUtils.isEmpty(mAuthToken)) {
          headers.add((mIsOAuth ? "Authorization" : "authToken"), (mIsOAuth ? "Bearer " : "") + mAuthToken);
      }
      return execution.execute(request, data);
  }
  </code></pre>
  
  <p><strong>LoggingClientHttpRequestInterceptor</strong>:</p>
  
  <pre><code>/** {@inheritDoc} */
  @Override
  public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
      Log.d(TAG, "To     : " + httpRequest.getURI());
      Log.d(TAG, "Method : " + httpRequest.getMethod().name());
      Log.d(TAG, "Data   : " + new String(bytes));
  
      for (Object key : httpRequest.getHeaders().keySet()) {
          Log.d(TAG, "Header &lt;" + key + "&gt;: " + httpRequest.getHeaders().get(key));
      }
  
      final ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest, bytes);
  
      if (response != null) {
          Log.d(TAG, "Response: " + response.getStatusCode());
          if (response.getBody() != null) {
              Log.d(TAG, "Response: " + convertStreamToString(response.getBody()));
          }
      } else {
          Log.d(TAG, "Response: " + response);
      }
  
      return response;
  }
  </code></pre>
  
  <p>The Rest Template is configured like this:</p>
  
  <pre><code>final RestTemplate template = new RestTemplate(false);
  template.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
  template.setRequestFactory(new BufferingClientHttpRequestFactory(template.getRequestFactory()));
  ApiUtils.addAuthTokenHeaderToRestTemplate(template, mAuthToken, false);
  ApiUtils.addRequestLoggingToRestTemplate(template);
  </code></pre>
  
  <p>The API call in question that crashed here is described in the Android annotations based interface:</p>
  
  <pre><code>@Post("/user/memberships")
  @Accept(MediaType.APPLICATION_JSON)
  CompanyApiResponse saveGroupMembership(UserGroupMembership membership) throws RestClientException;
  </code></pre>
  
  <p>Things I've tried:</p>
  
  <ul>
  <li>Removed LoggingInterceptor</li>
  <li>Called all API calls by CURL</li>
  <li>Removed call BufferingClientHttpRequestFactory - <strong>Helped a little but the error still occurs.</strong></li>
  <li>Tested it on Android 2.3 - <strong>the error cannot be reproduced</strong></li>
  </ul>
  
  <p>I've been reading various forums posts, the EOF exception seems to appear if URLs are incorrect, which I double checked in this case.</p>
  
  <p>Also of note, once the EOF Exception occurs, the call not even reaches the server side.</p>
  
  <p>Where would be a good point to continue the search for a fix? Is this a Android 4.1 inconvenience?</p>
  
  <p>While debugging this issue, I also found <a href="https://jira.springsource.org/browse/ANDROID-102" rel="noreferrer">https://jira.springsource.org/browse/ANDROID-102</a> which prevented me from seeing the real error (EOF) before.</p>
  
  <hr>
  
  <p><strong>Update:</strong> Just found <a href="http://code.google.com/p/google-http-java-client/issues/detail?id=116" rel="noreferrer">http://code.google.com/p/google-http-java-client/issues/detail?id=116</a> -  it might be related.</p>
  
  <p>The fix is also outlined in <a href="https://codereview.appspot.com/6225045/" rel="noreferrer">https://codereview.appspot.com/6225045/</a> - so it might've been merged for 4.1.</p>