title: java.lang.StackOverflowError Recursive Directory
body: <p>In my Android application I'm populating all of the paths of the external storage into an array.</p>
  
  <p>A small number of devices are reporting a <a href="http://developer.android.com/reference/java/lang/StackOverflowError.html" rel="nofollow noreferrer">StackOverflowError</a>.</p>
  
  <p>I've read <a href="https://stackoverflow.com/questions/860550/stack-overflows-from-deep-recursion-in-java">many linked posts</a> regarding the cause of this issue, but I don't know how to handle it or prevent it from happening within the code I'm using. Neither do I understand the 'recursive limit' that Android can handle.</p>
  
  <p>The code below is adapted <a href="http://gbifmetacat.googlecode.com/svn-history/r20/trunk/src/org/gbif/utils/DirecotoryRecursor.java" rel="nofollow noreferrer">from this source</a>.</p>
  
  <pre><code>private final Locale loc = SupportedLanguages.isSupported();
  private final String CACHE = "cache";
  private final String TEMP = "temp";
  
  @Override
  protected Boolean doInBackground(Void... params) {
  
          final File fileList = Environment.getExternalStorageDirectory();
  
          final String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath();
  
          final File[] dirList = fileList.listFiles();
  
          final List&lt;File&gt; listDirs = Arrays.asList(dirList);
  
          if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
  
              final ArrayList&lt;String&gt; dirPath = new ArrayList&lt;String&gt;();
              final ArrayList&lt;String&gt; dirName = new ArrayList&lt;String&gt;();
              String fileName = "";
  
              for (final File startingDirectory : listDirs) {
                  if (!startingDirectory.isFile() &amp;&amp; startingDirectory.canRead() &amp;&amp; !startingDirectory.isHidden()) {
  
                      final List&lt;File&gt; files = getFileListing(startingDirectory);
  
                      if (files != null) {
  
                          for (final File file : files) {
  
                              fileName = file.getPath().replaceAll(absolutePath, "").toLowerCase(loc).replaceAll("\\/", " ")
                                      .trim();
                              fileName = fileName.replaceAll(" +", " ");
  
                              dirName.add(fileName);
                              dirPath.add(file.toString());
                          }
                      }
                  }
              }
  
          } 
  
  
      return true;
  }
  
  private List&lt;File&gt; getFileListing(File aStartingDir) {
      List&lt;File&gt; result = getFileListingNoSort(aStartingDir);
  
      if (result != null &amp;&amp; !result.isEmpty()) {
          Collections.sort(result);
      }
      return result;
  }
  
  private List&lt;File&gt; getFileListingNoSort(File aStartingDir) {
      List&lt;File&gt; resultArray = new ArrayList&lt;File&gt;();
      File[] filesAndDirs = aStartingDir.listFiles();
  
      if (filesAndDirs != null &amp;&amp; filesAndDirs.length &gt; 0) {
  
          List&lt;File&gt; filesDirs = Arrays.asList(filesAndDirs);
  
          for (File file : filesDirs) {
              if (!file.isFile() &amp;&amp; file.canRead() &amp;&amp; !file.isHidden() &amp;&amp; !file.getName().toLowerCase(loc).startsWith(CACHE)
                      &amp;&amp; !file.getName().toLowerCase(loc).startsWith(TEMP)) {
  
                  resultArray.add(file);
                  List&lt;File&gt; deeperList = getFileListingNoSort(file);
                  resultArray.addAll(deeperList);
              }
          }
      }
  
      return resultArray;
  }
  </code></pre>
  
  <p>The crash log:</p>
  
  <pre><code>&gt; Caused by: java.lang.StackOverflowError at
  &gt; java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
  &gt; at java.lang.StringBuilder.append(StringBuilder.java:216) at
  &gt; java.io.File.join(File.java:215) at java.io.File.&lt;init&gt;(File.java:157)
  &gt; at java.io.File.&lt;init&gt;(File.java:124) at
  &gt; java.io.File.filenamesToFiles(File.java:852) at
  &gt; java.io.File.listFiles(File.java:791) at
  &gt; com.mypackage.name.ll.a(Unknown Source) at
  &gt; com.mypackage.name.ll.a(Unknown Source) at
  &gt; com.mypackage.name.ll.a(Unknown Source) at
  &gt; com.mypackage.name.ll.a(Unknown Source) at
  &gt; com.mypackage.name.ll.a(Unknown Source) at
  &gt; com.mypackage.name.ll.a(Unknown Source) at
  &gt; com.mypackage.name.ll.a(Unknown Source) at
  &gt; com.mypackage.name.ll.a(Unknown Source) at
  &gt; com.mypackage.name.ll.a(Unknown Source)
  </code></pre>
  
  <p>And so on......</p>
  
  <p>The proguard mapping:</p>
  
  <pre><code>com.mypackage.name.GenerateSubDirectoryList -&gt; com.mypackage.name.ll:
  java.util.List getFileListingNoSort(java.io.File) -&gt; a
  </code></pre>
  
  <p>Somewhere I'll need to count the recursions and apply a limit. But I don't know where or the limit that applies to Android or perhaps individual device hardware?</p>
  
  <p>Thanks in advance for your help.</p>