title: Jackson SAX parser throws exception when parsing huge JSON
body: <p>I'm trying to implement JSON array iterator with Jackson SAX parser (please, don't ask why).
  My app should work with huge files (up to 5 MiB), and that's a problem.</p>
  
  <p>That's how I initialize JsonParser and call iterator creation.
  I create InputStream initialized with JSON placed in \raw folder.</p>
  
  <pre>
      private JsonArrayIterator getIterator(String needle) throws IOException
      {
          InputStream inputStream = getApplicationContext().getResources().openRawResource(R.raw.products);
          inputStream.mark(-1);
  
          try {
          JsonParser jsonParser = createJsonParser(inputStream);
  
          // Some unrelated code
  
          return new JsonArrayIterator(jsonParser);
      } catch (IOException e) {
          e.printStackTrace();
      } finally {
          inputStream.close();
      }
  
          return null;
      }
  
  </pre>
  
  <p>And here is my iterator class.</p>
  
  <pre>
  
      private Object parseNextObject() throws IOException {
          // I'm not using ObjectMapper because of reasons
          HashMap nextObject = new HashMap();
  
          int objectsCount = 1;
  
          while (objectsCount > 0) {
              JsonToken currentToken = currentParser.nextValue();
  
              if(currentToken == JsonToken.START_OBJECT) {
                  ++objectsCount;
              }
              else if(currentToken == JsonToken.END_OBJECT) {
                  --objectsCount;
              }
              else if(currentToken == JsonToken.START_ARRAY) {
                  String currentName = currentParser.getCurrentName();
                  ArrayList list = new ArrayList(100);
                  JsonArrayIterator it = new JsonArrayIterator(currentParser);
  
                  while (it.hasNext()) {
                      list.add(it.next());
                  }
  
                  nextObject.put(currentName, list);
              }
              else {
                  // Here exception is throwed
                  nextObject.put(currentParser.getCurrentName(), currentParser.getText());
              }
          }
  
          currentParser.nextToken();  // Skip END_OBJECT
          return nextObject;
      }
  
  </pre>
  
  <p>It seem to work perfe... OH, WAIT.</p>
  
  <p>I have 3 sections (named arrays) in some huge file.
  It successfully parses first (a tiny one, under 1000 bytes). But I can't parse next.</p>
  
  <p>Next array has nested array with simple objects (like this):</p>
  
  <pre>
  
      {
          "properties":[
              {
                  "id":"1",
                  "title":"\u0426\u0432\u0435\u0442",
                  "values":[
                      {
                          "id":"1_2",
                          "title":"\u0427\u0435\u0440\u043d\u044b\u0439"
                      },
                      {
                          "id":"1_5005",
                          "title":"\u0417\u0435\u043b\u0435\u043d\u044b\u0439"
                      },
                      {
                          "id":"1_5006",
                          "title":"\u0421\u0435\u0440\u044b\u0439"
                      }
                  ]
              }
          ]
      }
  
  </pre>
  
  <p>For one object in values I call nextObject.put. currentParser.getCurrentName() is runs successfully and returns correct string, but currentParser.getText() fails. It's not a JSON problem: it perfectly being mapped on iOS. It's not an object or iterator creation problem: I can delete that where parser throws exception, but it will fail in the same place.</p>
  
  <p>Here is stack trace:</p>
  
  <pre>
  
      05-15 21:57:28.617: ERROR/AndroidRuntime(14758): FATAL EXCEPTION: main
      java.lang.NullPointerException: asset
      at android.content.res.AssetManager.readAsset(Native Method)
      at android.content.res.AssetManager.access$700(AssetManager.java:36)
      at android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:576)
      at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.loadMore(UTF8StreamJsonParser.java:174)
      at com.fasterxml.jackson.core.base.ParserBase.loadMoreGuaranteed(ParserBase.java:425)
      at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2(UTF8StreamJsonParser.java:1930)
      at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString(UTF8StreamJsonParser.java:1911)
      at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:276)
      at ru.studiomobile.JsonArrayIterator.parseNextObject(JsonArrayIterator.java:57)
      at ru.studiomobile.JsonArrayIterator.next(JsonArrayIterator.java:73)
      at ru.studiomobile.JsonArrayIterator.parseNextObject(JsonArrayIterator.java:47)
      at ru.studiomobile.JsonArrayIterator.next(JsonArrayIterator.java:73)
      at ru.studiomobile.MainActivity$2.onClick(MainActivity.java:81)
      at android.view.View.performClick(View.java:3127)
      at android.view.View$PerformClick.run(View.java:12025)
      at android.os.Handler.handleCallback(Handler.java:587)
      at android.os.Handler.dispatchMessage(Handler.java:92)
      at android.os.Looper.loop(Looper.java:132)
      at android.app.ActivityThread.main(ActivityThread.java:4126)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:491)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
      at dalvik.system.NativeStart.main(Native Method)
  
  </pre>
  
  <p>I noticed that there are something called Utf8StreamJsonParser. It has a field named _inputEnd equal 4000 (why 4000?). When other field, _inputPtr, become bigger it throw an exception. How do I can handle it? I tried to use BufferedInputStream with predefined block size instead of InputStream but it had no effect.</p>
  
  <h2>Update</h2>
  
  <p>Info about some lines</p>
  
  <pre>
  
      47: list.add(it.next());  
      73: return parseNextObject();  
      75: e.printStackTrace();
  
  </pre>
  
  <p>Nothing special.</p>