I have a configuration file that I pick up from the server at the launch of my android app. The code for fetching the file is pretty standard
@Override
protected void onResume() {
    super.onResume();
    new ConnectionTask().execute();
}
private class ConnectionTask extends AsyncTask<String, String, String> {
    @Override
    protected void onPreExecute() {
    }
    @Override
    protected String doInBackground(String... args) {
        String result = null;
        AuthenticateConnection mAuth1 = new AuthenticateConnection();
        try {
            result = mAuth1.connection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    @Override
    protected void onPostExecute(String str) {
        if (!isFinishing() && !isDestroyed()) {
            if (!TextUtils.isEmpty(str)) {
                Log.e("str", "" + str);
                /****** The below line crashes*******/
                BaseUrl obj = new Gson().fromJson(str, BaseUrl.class);
                /****** The above line crashes*******/
                //Some Logic here
            } 
        }
    }
}
private class AuthenticateConnection {
    public AuthenticateConnection() {
    }
    public String connection() throws Exception {
        String str = "";
        try {
            // Create a URL for the desired page
            if (!TextUtils.isEmpty(getApplicationContext().getResources().getString(R.string.configuration_url))) {
                String aUrl = getApplicationContext().getResources().getString(R.string.configuration_url);
                URL url = new URL("http://" + aUrl);
                str = convertStreamToString(url.openStream());
            } else {
                str = "";
            }
        } catch (MalformedURLException e) {
        } catch (IOException e) {
        }
        return str;
    }
    public String convertStreamToString(InputStream is) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
        e.printStackTrace();
        } finally {
            try {
            is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}
I am getting a strange exception while parsing the file. I and my team have not encountered this error in all our unit testing but Crashlytics reports a lot of user facing this exception, here in onPostExecute(), while parsing the json, BaseUrl obj = new Gson().fromJson(str, BaseUrl.class);
What could be the potential reasons for this exception.
Fatal Exception: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(SourceFile:200)
       at com.google.gson.Gson.fromJson(SourceFile:810)
       at com.google.gson.Gson.fromJson(SourceFile:775)
       at com.google.gson.Gson.fromJson(SourceFile:724)
       at com.google.gson.Gson.fromJson(SourceFile:696)
       at com.myapp.activity.Splash$ConnectionTask.onPostExecute(SourceFile:263)
       at com.myapp.activity.Splash$ConnectionTask.onPostExecute(SourceFile:237)
       at android.os.AsyncTask.finish(AsyncTask.java:632)
       at android.os.AsyncTask.access$600(AsyncTask.java:177)
       at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:136)
       at android.app.ActivityThread.main(ActivityThread.java:5095)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
       at dalvik.system.NativeStart.main(NativeStart.java)
Caused by java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
       at com.google.gson.stream.JsonReader.beginObject(SourceFile:387)
       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(SourceFile:189)
       at com.google.gson.Gson.fromJson(SourceFile:810)
       at com.google.gson.Gson.fromJson(SourceFile:775)
       at com.google.gson.Gson.fromJson(SourceFile:724)
       at com.google.gson.Gson.fromJson(SourceFile:696)
       at com.myapp.activity.Splash$ConnectionTask.onPostExecute(SourceFile:263)
       at com.myapp.activity.Splash$ConnectionTask.onPostExecute(SourceFile:237)
       at android.os.AsyncTask.finish(AsyncTask.java:632)
       at android.os.AsyncTask.access$600(AsyncTask.java:177)
       at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:136)
       at android.app.ActivityThread.main(ActivityThread.java:5095)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
       at dalvik.system.NativeStart.main(NativeStart.java)
The reference json is that is stored in the configuration file is as below, and BaseUrl.java conforms to this json:
{ "baseUrls": [{
    "versionCode": 10,
    "baseUrl": "http://myapp.in",
    "infra": "staging"
},{
        "versionCode": 11,
        "baseUrl": "http://myapp.in",
        "infra": "production"
}]
}
Adding BaseUrl.java to the Question:
public class BaseUrl implements Parcelable {
    ArrayList<VersionControl> baseUrls;
    public ArrayList<VersionControl> getBaseUrls() {
        return baseUrls;
    }
    public void setBaseUrls(ArrayList<VersionControl> baseUrls) {
        this.baseUrls = baseUrls;
    }
    protected BaseUrl(Parcel in) {
        if (in.readByte() == 0x01) {
            baseUrls = new ArrayList<VersionControl>();
            in.readList(baseUrls, VersionControl.class.getClassLoader());
        } else {
            baseUrls = null;
        }
    }
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        if (baseUrls == null) {
            dest.writeByte((byte) (0x00));
        } else {
            dest.writeByte((byte) (0x01));
            dest.writeList(baseUrls);
        }
    }
    @SuppressWarnings("unused")
    public static final Parcelable.Creator<BaseUrl> CREATOR = new Parcelable.Creator<BaseUrl>() {
        @Override
        public BaseUrl createFromParcel(Parcel in) {
            return new BaseUrl(in);
        }
        @Override
        public BaseUrl[] newArray(int size) {
            return new BaseUrl[size];
        }
    };
}
 
     
     
    