51

I am using the new FaceBook SDK 3.0. While posting images from the URL to "me/photos", I am intermittently getting an EOFException. I am getting this error once in a while (~1 in 20 times).

I must also add that just after getting the EOFException if I retry the posting again, it posts successfully.

So, for the time being I have coded to automatically retry one more time if I get EOFException and the solution seems satisfactory.

But I need to know what is causing it, Is it a bug in Android SDK. I Googled about it a lot but could not get anything.

I'm posting the logs (removing my access token and image URL for security reasons)

06-05 15:09:42.585: D/FacebookSDK.Request(16611): Request:
06-05 15:09:42.585: D/FacebookSDK.Request(16611):   Id: 9
06-05 15:09:42.585: D/FacebookSDK.Request(16611):   URL:https://graph.facebook.com/me/photos?caption=abc&format=json&sdk=android&migration_bundle=fbsdk%3A20121026&access_token=ADBCEFG&url=http%3A%2F%2Ftest.test.test%2Ftest%2Ftest%2F201695%2Ftest%2F18629
06-05 15:09:42.585: D/FacebookSDK.Request(16611):   Method: POST
06-05 15:09:42.585: D/FacebookSDK.Request(16611):   User-Agent: FBAndroidSDK.3.0.0
06-05 15:09:42.585: D/FacebookSDK.Request(16611):   Content-Type:   multipart/form-data; boundary=3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f
06-05 15:09:42.585: D/FacebookSDK.Request(16611):   Parameters:
06-05 15:09:42.585: D/FacebookSDK.Request(16611):       caption:    abc
06-05 15:09:42.585: D/FacebookSDK.Request(16611):       format: json
06-05 15:09:42.585: D/FacebookSDK.Request(16611):       sdk:    android
06-05 15:09:42.585: D/FacebookSDK.Request(16611):       migration_bundle:   fbsdk:20121026
06-05 15:09:42.585: D/FacebookSDK.Request(16611):       access_token:   ABCDEF
06-05 15:09:42.585: D/FacebookSDK.Request(16611):       url:    http://test.test.test/test/test/201695/test/18629
06-05 15:09:42.585: D/FacebookSDK.Request(16611):   Attachments:
06-05 15:09:42.600: D/FacebookSDK.Response(16611): Response <Error>: java.io.EOFException
sathish kumar
  • 141
  • 1
  • 13
Gaurav Vashisth
  • 7,547
  • 8
  • 35
  • 56
  • Had an error like this too in Spring Android. Had to do with something about http.keepalive property of the System class. Might be worth looking into. – tolgap Jun 05 '13 at 15:43
  • 1
    In this case, EOFException means there is no more data to be read, which (again in this case) can only mean that the file is empty. – Himanshu Joshi Oct 22 '13 at 07:52
  • Any one find solution for this error? – user2106897 Feb 17 '14 at 05:44
  • I've also coded a retry when error.getErrorMessage().contains("EOF"), i think that it is a bug in ice-cream-sandwich, see https://code.google.com/p/android/issues/detail?id=24672 – jmhostalet Mar 09 '14 at 23:55
  • Can you post the code that shows how you are "POST"ing to "me/photos"? Might just be a corner case or glitch when uploading. Had a lot of them. – napkinsterror Aug 01 '15 at 06:33
  • Hey @napkinsterror I posted this so long ago, so now I have no idea about my question., – Gaurav Vashisth Aug 05 '15 at 07:30
  • Okay sorry. Thanks for letting me know – napkinsterror Aug 06 '15 at 14:25
  • if it is not worth an answer, please vote to close it. – Murtaza Khursheed Hussain Nov 03 '15 at 04:34
  • It would help to show how your handling the OutputStream logic. It might be more descriptive to see if your byte buffers are being handled correctly, or if there is an issue with the Dalvik trying to GC the bytes your reading within your while loop. (This can sometimes be an issue with how the code is compiled for performance. So if you don't want to share here, you can check the decompiled code in your IDE to see if the compiler made some 'helpful adjustments') – Chris Sullivan Jan 25 '16 at 15:17

2 Answers2

1

The problem

This is a HttpURLConnection related issue. The actual socket used for the connection is selected from a pool. Most servers create persistent connections (Connection: Keep-Alive header) in order to reuse existing sockets which is cheaper than creating a new one every single time. The problem comes from the fact that these sockets are open for a certain period of time, mostly 60 seconds or so, then they are closed and cannot be reused. The Android OS, however, tries to use the same socket as it thinks that the socket is still good since it was assigned to the same host, so it starts sending packages waiting for ACK and other response packages, which never come since the socket is not open anymore, though it's been expecting some answer, hence the EOFException.

The solution

Step 1 - Limit the pool size to a relatively small number

private static final int MAX_CONNECTIONS = 5;
// ...
static {
    System.setProperty("http.maxConnections", String.valueOf(MAX_CONNECTIONS));
}

Step 2 - Implement a retry mechanism

Wherever you use the Facebook code and get an EOFException, wrap it in a try-catch that catches the exception and retries connecting to the URL up to the max pool size. Here's a method stub, that could be used (I don't know the Facebook SDK, hence the TODO's):

private void connect(int retryNumber) {
    try {
        // TODO your facebook code goes here
    } catch (EOFException e) {
        if (retryNumber > MAX_CONNECTIONS) {
            // TODO handle exception, it's over the limit, so it is a different problem
        } else {
            // TODO disconnect first, if possible
            connect(retryNumber + 1);
        }
    } catch (Exception e) {
        // TODO other exception handling
    } finally {
        // TODO disconnect, if possible
    }
} 

Of course, you have to call this method with 0 retryNumber (connect(0);) the first time.

Gergely Kőrössy
  • 5,620
  • 3
  • 28
  • 44
0

It sounds like you may be having some internet connectivity issues.

You could write to some retrylogic to handle this exception by having it submit again, or see if the class you're using to upload has a way to increase the timeout for the transaction!

CloudyOne
  • 161
  • 1
  • 6