1

I'm trying to read some information from an url using HttpURLConnection, however, when I try to run it I get:

java.lang.RuntimeException: Unable to start activity ComponentInfo{...}: java.lang.NullPointerException: println needs a message.

I've seen plenty examples that do just this, so what's the problem? I've double checked the url, when I copy/paste it to a web browser I get the message I'm supposed to get, no problems. I use the same url to get information to a different program (written in C++) and there it works just fine. Is there a connection setting I've missed or something?

Here's the code, the problem occurs at "InputStream stream = connection.getInputStream();":

public String download_organisations(String url){
    String jsonString = "";
    try {
        if(!url.startsWith("http://")){
            url = "http://" + url;
        }
        if(url.endsWith("/")){
            url = url.substring(0, url.lastIndexOf("/"));
        }
        url = url + SystemStatic.URL_SERVICE_WEB_ORGANISATION_MANAGER;

        Log.d("OrganisationManager-Android","url: " + url);
        URL httpUrl = new URL(url);

        HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();
        connection.setConnectTimeout(10000);


        InputStream stream = connection.getInputStream();

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = stream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        buffer.flush();
        byte[] inputStreamByteArray = buffer.toByteArray();

        byte[] base64 = Base64.decode(inputStreamByteArray, 0);
        byte[] decrypted = CipherUtils.decrypt(base64);

        jsonString = decrypted.toString();

        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            Log.d("OrganisationManager-Android", "Download succeded with response: " + connection.getResponseCode());
        } else {
            Log.d("OrganisationManager-Android", "Download failed with response: " + connection.getResponseCode());
        }
    } catch (MalformedURLException e) {
        Log.e("OrganisationManager-Android", e.getMessage());

    } catch (IOException e) {
        Log.e("OrganisationManager-Android", e.getMessage());

    } catch (Exception e) {
        Log.e("OrganisationManager-Android", e.getMessage());

    }

    return jsonString;
}

Error stack:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.organisationmanager.cin, PID: 2066
              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.organisationmanager.cin/com.organisationmanager.ble.ScanningActivity}: java.lang.NullPointerException: println needs a message
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3194)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302)
                  at android.app.ActivityThread.-wrap12(Unknown Source:0)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
                  at android.os.Handler.dispatchMessage(Handler.java:108)
                  at android.os.Looper.loop(Looper.java:166)
                  at android.app.ActivityThread.main(ActivityThread.java:7425)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
               Caused by: java.lang.NullPointerException: println needs a message
                  at android.util.Log.println_native(Native Method)
                  at android.util.Log.e(Log.java:261)
                  at com.organisationmanager.ble.common.OrganisationManagerWebPortalCommunicationHelper.download_organisations(OrganisationManagerWebPortalCommunicationHelper.java:210)
                  at com.organisationmanager.ble.ScanningActivity.onCreate(ScanningActivity.java:184)
                  at android.app.Activity.performCreate(Activity.java:7372)
                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3147)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302) 
                  at android.app.ActivityThread.-wrap12(Unknown Source:0) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891) 
                  at android.os.Handler.dispatchMessage(Handler.java:108) 
                  at android.os.Looper.loop(Looper.java:166) 
                  at android.app.ActivityThread.main(ActivityThread.java:7425) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) 
Kurodani
  • 115
  • 10
  • 1
    Please show us the entire code. Which URL are you trying to hit, and have you verified that it is reachable e.g. from your mobile web browser or local computer? – Tim Biegeleisen Aug 13 '18 at 15:00
  • Could you please show also the full error stack? – Salvatore Aug 13 '18 at 18:37
  • Please share more information .where is `print` statement which throwing `NPE` – Godfather Aug 13 '18 at 18:39
  • @TimBiegeleisen I expanded the code to include the entire class, although I don't think that it helps with my current issue. Regarding the URL, as I said in my post I did verify it with my web browser and it is both reachable and gives the correct response. – Kurodani Aug 14 '18 at 06:30
  • Did you take that URL directly from your Java code, while it is running, or is that URL what you assume the code is using? Really the best thing for you to do now is to _debug_ your code. Add a breakpoint in Android Studio, then step through the method line by line until you see something. – Tim Biegeleisen Aug 14 '18 at 06:37
  • @Salvatore error stack added – Kurodani Aug 14 '18 at 06:41
  • @TimBiegeleisen I did run in debug mode, had a break point at "HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();" and stepped through, which is how I found that the issue was with the inputstream. The adress I checked was copied from the url info in the HttpURLConnection "connection" when the program was stopped. – Kurodani Aug 14 '18 at 06:44

2 Answers2

1

The error stack says:

Caused by: java.lang.NullPointerException: println needs a message at android.util.Log.println_native(Native Method) at android.util.Log.e(Log.java:261)

As you can see from these lines, the exception was thrown by Log.e() in one of the catch blocks inside download_organisations() (either the one that catches the MalformedURLException, or the one that catches the IOException, or the one that catches the Exception).

You handle exceptions in catch blocks by logging their message. But maybe their message is null, so println doesn't have a valid message to print and throws the NullPointerException.

Try logging e instead, and check if "java.lang.NullPointerException: println needs a message" is thrown again. Do like this:

} catch (IOException e) {
        Log.e("OrganisationManager-Android", e.toString());
}

Otherwise you can print the stack trace of the caught exception:

} catch (IOException e) {
        Log.e("OrganisationManager-Android");
        e.printStackTrace()
}
Salvatore
  • 499
  • 10
  • 16
  • Thank you! That gave me a new error code: E/OrganisationManager-Android: android.os.NetworkOnMainThreadException Still don't know what the real problem is, but it helps to get the correct error message. it wouldn't let me use just "e", but I used "e.toString()" and that worked. Why didn't "e.getMessage()" work though? I thought that was the most common way to get the error message... – Kurodani Aug 14 '18 at 12:29
  • This error is thrown because you are making an HTTP request on the main thread. This behavior blocks the application untill the request is not completed: then, the user won't be able to use the app and will give them a bad user experience. You should use an [`AsyncTask`](https://developer.android.com/reference/android/os/AsyncTask.html) or, if you need to load the request results on the UI, a [`Loader`](https://developer.android.com/guide/components/loaders) (although deprecated since API 28), as [this](https://developer.android.com/guide/components/processes-and-threads) page says. – Salvatore Aug 14 '18 at 14:19
  • @Kurodani has this solution been useful? – Salvatore Aug 16 '18 at 21:59
  • sorry for the slow reply, yes this was helpful! – Kurodani Aug 21 '18 at 09:40
0

check you get have permison in Your app in manifest?

if You dont use it try it :

in AndroidManifest add this code outside Tag Apliciation

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />