Index: lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java =================================================================== --- lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (revision 1458959) +++ lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (working copy) @@ -17,6 +17,7 @@ * limitations under the License. */ +import java.io.FileNotFoundException; import java.io.IOException; import java.io.Reader; import java.io.StringReader; @@ -1627,4 +1628,75 @@ iw.close(); dir.close(); } + + public void testTooManyFileException() throws Exception { + + // Create failure that throws Too many open files exception randomly + MockDirectoryWrapper.Failure failure = new MockDirectoryWrapper.Failure() { + + @Override + public MockDirectoryWrapper.Failure reset() { + doFail = false; + return this; + } + + @Override + public void eval(MockDirectoryWrapper dir) throws IOException { + if (doFail) { + if (random().nextBoolean()) { + throw new FileNotFoundException("some/file/name.ext (Too many open files)"); + } + } + } + }; + + MockDirectoryWrapper dir = newMockDirectory(); + // The exception is only thrown on open input + dir.setFailOnOpenInput(true); + dir.failOn(failure); + + // Create an index with one document + IndexWriterConfig iwc = new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())); + IndexWriter iw = new IndexWriter(dir, iwc); + Document doc = new Document(); + doc.add(new StringField("foo", "bar", Field.Store.NO)); + iw.addDocument(doc); // add a document + iw.commit(); + DirectoryReader ir = DirectoryReader.open(dir); + assertEquals(1, ir.numDocs()); + ir.close(); + iw.close(); + + // Open and close the index a few times + for (int i = 0; i < 100; i++) { + failure.setDoFail(); + iwc = new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())); + //iwc.setOpenMode(OpenMode.APPEND); // the test passes with APPEND!! + //iwc.setInfoStream(System.out); + try { + iw = new IndexWriter(dir, iwc); + } catch (CorruptIndexException ex) { + // Exceptions are fine - we are running out of file handlers here + continue; + } catch (FileNotFoundException ex) { + continue; + } + failure.clearDoFail(); + iw.close(); + ir = DirectoryReader.open(dir); + assertEquals("lost document after iteration: " + i, 1, ir.numDocs()); + ir.close(); + } + + // Check if document is still there + failure.clearDoFail(); + ir = DirectoryReader.open(dir); + assertEquals(1, ir.numDocs()); + ir.close(); + + dir.close(); + } + + + } Index: lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java (revision 1458959) +++ lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java (working copy) @@ -22,7 +22,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.io.IOExceptionWithCause; +import org.apache.lucene.index.SegmentInfos.FindSegmentsFile; import org.apache.lucene.search.SearcherManager; // javadocs import org.apache.lucene.store.Directory; @@ -322,6 +325,23 @@ new SegmentInfos().read(directory); return true; } catch (IOException ioe) { + /*// NOCOMMIT - with this fix the test passes just as a PoC + final AtomicInteger i = new AtomicInteger(); + try { + new FindSegmentsFile(directory) { + + @Override + protected Object doBody(String segmentFileName) throws IOException { + i.incrementAndGet(); + new SegmentInfos().read(directory, segmentFileName); + + return null; + } + }.run(); + } catch (IOException ex) { + } + return i.get() > 0; + */ return false; } }