title: NullPointerException using Retrofit library - Android
body: <h3><em>(Scroll at the end of question to see the final solution)</em></h3>
  
  <p>Playing around with the Retrofit Android library. I am trying to push a POST request into a web server that is supposed to return 3 fields after a successful call to a "/login" method through POST. Information:</p>
  
  <ol>
  <li>End point: <a href="http://example.us.es:3456" rel="nofollow">http://example.us.es:3456</a></li>
  <li>Server-side method to perform the login: <em>/login</em></li>
  <li>Required parameters to the server-side method: "user" and "password"</li>
  <li>HTTP method allowed by server administrator: POST</li>
  </ol>
  
  <p>No matter what values for "user" and "password" the app client enters, the web server should send a single JSONObject containing three fields:</p>
  
  <ol>
  <li><strong>ok</strong>: string with values "true" or "false" (false would mean that the credentials were not valid).</li>
  <li><strong>msg</strong>: would carry a string message in case there was an error (for example, invalid credentials or database error)</li>
  <li><strong>data</strong>: another JSONObject that in this method contains one single name/value pair, the <em>id_session</em> (string containing the session identifier). Other methods contain several name/value pairs; this is not the case for the <em>login</em> method.</li>
  </ol>
  
  <p>Basing myself in this information, the first thing I did is create a POJO Java method that looks like this:</p>
  
  <h1>POJO Method (<em>LoginInfo_POJO.java</em>)</h1>
  
  <pre><code>package com.example.joselopez.prueba1;
  
  import java.util.List;
  
  public class LoginInfo_POJO {
      public String _ok;
      public String _msg;
      public Dataset _dataset;
  
      class Dataset {
          String _idsession;
      }
  }
  </code></pre>
  
  <p>The next thing I did is create an interface containing the login method (I'd add other methods here after I can successfully log in):</p>
  
  <h1>API METHODS IN INTERFACE (<em>IApiMethods.java</em>)</h1>
  
  <pre><code>package com.example.joselopez.prueba1;
  
  import retrofit.http.POST;
  import retrofit.http.Query;
  
  public interface IApiMethods {
  
      // Log-in method
      @FormUrlEncoded
      @POST("/login")
      LoginInfo_POJO logIn(@Query("user") String user,
                      @Query("password") String password);
  }
  </code></pre>
  
  <p>Almost there. Now I create a class that extends from AsyncTask that will perform the networking operations in a separate thread. This class is inside the "MainActivity.java" file.</p>
  
  <h1>Main Activity (<em>MainActivity.java</em>)</h1>
  
  <pre><code>...
  ...
  
  
  private class BackgroundTask_LogIn extends AsyncTask&lt;Void, Void, LoginInfo_POJO&gt; {
      RestAdapter restAdapter;
  
      @Override
      protected LoginInfo_POJO doInBackground(Void... params) {
          IApiMethods methods = restAdapter.create(IApiMethods.class);
          LoginInfo_POJO loginInfo = methods.logIn(mUser, mPassword);
          return loginInfo;
      }
  
      @Override
      protected void onPreExecute() {
          restAdapter = new RestAdapter.Builder()
                  .setEndpoint("http://example.us.es:3456")
                  .build();
      }
  
      @Override
      protected void onPostExecute(LoginInfo_POJO loginInfo_pojo) {
          tv.setText("onPostExecute()");
          tv.setText(loginInfo_pojo._ok + "\n\n");
          tv.setText(tv.getText() + loginInfo_pojo._msg + "\n\n");
          tv.setText(tv.getText() + loginInfo_pojo.data.id_sesion);
          }
      }
  }
  </code></pre>
  
  <p>The MainActivity layout contains a single TextView (inside a RelativeLayout) whose id is "textView", and is instantiated in code as "tv" as you will see next. The complete code for MainActivity is:</p>
  
  <h1>Main Activity (<em>MainActivity.java</em>)</h1>
  
  <pre><code>package com.example.joselopez.prueba1;
  
  import android.os.AsyncTask;
  import android.os.Bundle;
  import android.support.v7.app.AppCompatActivity;
  import android.util.Log;
  import android.widget.TextView;
  import retrofit.RestAdapter;
  
  public class MainActivity extends AppCompatActivity {
  
  TextView tv;
  String mUser, mPassword;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
  
      setContentView(R.layout.activity_main);
      tv = (TextView) findViewById(R.id.textView);
      mUser = "test_user";
      mPassword = "test_password";
  
      BackgroundTask_LogIn tryLogin = new BackgroundTask_LogIn();
      tryLogin.execute();
  }
  
  private class BackgroundTask_LogIn extends AsyncTask&lt;Void, Void, LoginInfo_POJO&gt; { ... }
  </code></pre>
  
  <p>Everything should be working. But it is not, and after a bit of debugging I found that the onPostExecute() method inside class BackgroundTask_LogIn stops in line:</p>
  
  <pre><code>for (LoginInfo_POJO.Dataset dataset : loginInfo_pojo._dataset) {
  </code></pre>
  
  <p>The error thrown is:</p>
  
  <blockquote>
    <p>com.example.joselopez.prueba1 E/AndroidRuntime﹕ FATAL EXCEPTION: main
        java.lang.NullPointerException</p>
  </blockquote>
  
  <p>So I set a breakpoint at this line and guess what? My LoginInfo_POJO instance is holding these values for its internal variables:</p>
  
  <ul>
  <li>_ok = null</li>
  <li>_msg = null</li>
  <li>_dataset = null</li>
  </ul>
  
  <p>This means my variables aren't being populated from the server response, BUT the connection seems to be successful as the doInBackground method runs entirely and onPostExecute is being called.</p>
  
  <p>So what do you think? Maybe I am not carrying out the POST request the right way?</p>
  
  <hr>
  
  <h1>UPDATE</h1>
  
  <p>As @Gaëtan said, I made a huge error in my POJO class; local variable names there MUST be EQUAL to those in the resulting JSON. I said that I was expecting fields "ok", "msg", "data" and "id_session" from the JSON, but the local variables inside my LoginInfo_POJO have names "_ok", "_msg", "_dataset", "_idsession" (notice the leading underscores). This is a huge error from a Retrofit perspective, so rewriting the POJO method accounting for this will eventually solve the problem.</p>