4

Attempt to invoke virtual method 'void java.io.BufferedReader.close()' on a null object reference this Exception is thrown by JRE please help!!

here is the class

package com.example.MovieMania.fragmentTv;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;





import com.example.MovieMania.R;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.AdapterView.OnItemClickListener;

public class BackgroundTaskTv extends AsyncTask<String, Void, String[]> {

    final String DEF_BASE_URL = "http:api.themoviedb.org/3/tv/popular?[api_key]";

    private final Context context;

    public BackgroundTaskTv(Context context) {
        this.context = context;
    }

    public static String JsonStr;  // so that JSONstring can be used by other activities

    private String[] jsonParse(String movieJsonStr) throws JSONException {

        final String POSTER_PATH = "poster_path"; // JSON STRING PARSING AND
                                                    // RETURN
                                                    // POSTER PATHS

        JSONObject jsonObj = new JSONObject(movieJsonStr);
        JSONArray resultArray = jsonObj.getJSONArray("results");

        int len =resultArray.length();
        String[] posters = new String[len];
        for (int i = 0; i < len; i++) {
            posters[i] = resultArray.getJSONObject(i).getString(POSTER_PATH);
        }

        for (String res : posters)
            Log.v(POSTER_PATH, res);

        return posters;

    }

    @Override
    protected String[] doInBackground(String... params) {



        String movieJsonStr = null;
        InputStream inputStream = null;


        String FINAL_URL=DEF_BASE_URL;
        ImageAdapterTv.poster_paths.clear();

        BufferedReader reader = null;
        HttpURLConnection urlConnection = null; // READ THE INPUTSTREAM AND
                                                // GET THE JSONSTRING
        try {
            URL url = new URL(FINAL_URL);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            // Read the input stream into a String
            inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            if (inputStream == null) {
                // Nothing to do.
                return null;
            }

            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null) {
                // Since it's JSON, adding a newline isn't necessary (it
                // won't affect parsing)
                // But it does make debugging a *lot* easier if you print
                // out the completed
                // buffer for debugging.
                buffer.append(line + "\n");
            }

            if (buffer.length() == 0) {
                // Stream was empty. No point in parsing.
                return null;
            }

            movieJsonStr = buffer.toString();
            JsonStr=movieJsonStr;

            Log.v("Tv string: ", movieJsonStr);
        } catch (Throwable e) {
            Log.e("backgroundtask", "EXCEPTION", e);
        } finally {
            urlConnection.disconnect();
            try {
                reader.close();
                inputStream.close();
            } catch (IOException e) {
                Log.e("READER.CLOSE()", e.toString());
            }
        }

        try {
            return jsonParse(movieJsonStr);
        } catch (JSONException e) {
            Log.e("BACKGROUNDTASK", "EXCEPTION FROM jsonParse()", e);
        }

        return null;
    }

    @Override
    protected void onPostExecute(String[] result) {
        if (ImageAdapterTv.poster_paths.isEmpty()) {
            for (String s : result) {
                ImageAdapterTv.poster_paths.add(s);
            }
        }

        final Activity activity = (Activity) context;
        activity.runOnUiThread(new Runnable() {
            @Override
            // this code is written so that the grid view is populated after
            // backgroundTask
            public void run() { // produce results so that there is no blank
                                // screen on launch
                GridView grid = (GridView) activity.findViewById(R.id.gridview_tv);
                grid.setAdapter(new ImageAdapterTv(context));

                grid.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
                        String path=ImageAdapterTv.poster_paths.get(position);
                        Intent intent=new Intent(context,DetailActivityTv.class);
                        intent.putExtra("poster", path);
                        intent.putExtra("POSITION", position);
                        activity.startActivity(intent);
                        }
                });

                }
        });
    }

}

It is a background thread which is getting the json response from an api I dont know why this exception is thrown.

Nitish Chopra
  • 273
  • 1
  • 4
  • 11
  • Why don't you remove the try catch surrounding the initalization of the BufferedReader, and see weather it crashes. – SuperFrog Oct 16 '15 at 20:10

5 Answers5

5

if exception happened before initializing the reader it will lead to this error because reader.close() is placed in finally block. It's good practice to always check for null before closing resources in finally

if(reader != null)
    reader.close();
if(inputStream != null)
    inputStream.close();
Ahmed Sayed
  • 452
  • 1
  • 8
  • 15
  • 1
    Thanks it worked but now its throwing another exception Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference what do i do now??? – Nitish Chopra Oct 16 '15 at 20:40
  • That's not a good approach. You should check for null, yes. But before that check why you're getting null. – SuperFrog Oct 16 '15 at 20:45
1

You need to check "Null" in the finally . Something is happening, and reader not created.

            try {
                if (reader != null) reader.close();
                if (inputStream!= null) inputStream.close();
            } catch (IOException e) {
                Log.e("READER.CLOSE()", e.toString());
            }

You do return null, but the finally is done. And in it BufferedReader reader = null;. See example:

public static void main(String[] args){
    System.out.println(0);
    Object o = get();
    System.out.println(2);
}

public static Object get(){
    try {
        System.out.println(1);
        return null;
    } catch (Exception e){

    } finally {
        System.out.println("finally");
    }
    return null;
}

Output:

0 1 finally 2

user2413972
  • 1,355
  • 2
  • 9
  • 25
  • I answered the first, and you have chosen a different answer correct. Lol. Horrible world ... It seems to me that you do not understand how work finally. It is always satisfied. – user2413972 Oct 16 '15 at 20:44
1

It maybe caused because of exception in your urlconnection or your inputstream is null.

if (inputStream == null)
return null;

Your code will run finally block if exception is thrown or return is called from inputstream null checking.

Reader object to be created using inputstream is never created. So when you try close() method it's throwing null pointer exception.

You should always use null checking before using close() method on streams and readers, writers.

Sudheer
  • 228
  • 1
  • 4
  • 13
  • Thanks it worked but now its throwing another exception Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference what do i do now??? – Nitish Chopra Oct 16 '15 at 20:40
  • I can't find where your trying to access the string length in your background task. Exception maybe caused in some other part of app. – Sudheer Oct 16 '15 at 20:55
1

As it is seen from the discription the exception occurs when you are trying to close the BufferedReader reader object in the finally block as it is null at that moment. It happens because you get some other exception in your try block wich occurs before you initialize the reader or because your return statement is called, i.e somewhere in this piece of code:

        URL url = new URL(FINAL_URL);
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestMethod("GET");
        urlConnection.connect();

        // Read the input stream into a String
        inputStream = urlConnection.getInputStream();
        StringBuffer buffer = new StringBuffer();
        if (inputStream == null) {
            // Nothing to do.
            return null;
        }

To avoid such situation, you should check your reader and inputStream for null before closing like this:

if(reader != null) {
    reader.close;
    reader = null;
}
if(inputStream != null) {
    inputStream.close;
    inputStream = null;
}

Besides take a look at this post about catching Throwables: Is it a bad practice to catch Throwable?

Anyway, I think you shall find out why does this flow takes place as it is not what you want as far as I can understand

Why have you moved this block of code outside the first try-catch?:

try {
        return jsonParse(movieJsonStr);
    } catch (JSONException e) {
        Log.e("BACKGROUNDTASK", "EXCEPTION FROM jsonParse()", e);
    }

You can catch multiple types of exceptions from one try{}, you just have to specify them one by one. As written above, when something goes wrong(and it does) you are finishing previous try-catch block before creating reader and everything after that. Therefore in this place your movieJsonStr is also null, and you are passing it forward to create a JSONOblect from it. This is where your next exception comes from. Move the return jsonParse(movieJsonStr); string to the place where you are certain it is the string you want to process.

Community
  • 1
  • 1
Sasha
  • 86
  • 5
0

sometimes this is the problem because of you are closing the BufferedReader which is not assigned any value or its value is null. so it throwing exception java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.BufferedReader.close()' on a null object reference to overcome this problem : goto your manifest file and give INTERNET permission