Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 953441) +++ lucene/CHANGES.txt (working copy) @@ -481,6 +481,10 @@ files when a mergedSegmentWarmer is set on IndexWriter. (Mike McCandless) +* LUCENE-2496: Don't throw NPE if IndexWriter is opened with CREATE on + a prior (corrupt) index missing its segments_N file. (Mike + McCandless) + New features * LUCENE-2128: Parallelized fetching document frequencies during weight Index: lucene/src/test/org/apache/lucene/index/TestIndexWriter.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestIndexWriter.java (revision 953441) +++ lucene/src/test/org/apache/lucene/index/TestIndexWriter.java (working copy) @@ -4954,5 +4954,32 @@ writer.close(); assertEquals("expected a no-op close after IW.rollback()", 0, dir.listAll().length); } - + + public void testNoSegmentFile() throws IOException { + File tempDir = _TestUtil.getTempDir("noSegmentFile"); + try { + Directory dir = FSDirectory.open(tempDir); + dir.setLockFactory(new NoLockFactory()); + IndexWriter w = new IndexWriter(dir, new IndexWriterConfig( + TEST_VERSION_CURRENT, new MockAnalyzer()) + .setMaxBufferedDocs(2)); + + Document doc = new Document(); + doc.add(new Field("c", "val", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS)); + w.addDocument(doc); + w.addDocument(doc); + String[] files = dir.listAll(); + for(String file : files) { + System.out.println("file=" + file); + } + IndexWriter w2 = new IndexWriter(dir, new IndexWriterConfig( + TEST_VERSION_CURRENT, new MockAnalyzer()) + .setMaxBufferedDocs(2).setOpenMode(OpenMode.CREATE)); + + w2.close(); + dir.close(); + } finally { + _TestUtil.rmDir(tempDir); + } + } } Index: lucene/src/java/org/apache/lucene/index/IndexFileDeleter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/IndexFileDeleter.java (revision 953441) +++ lucene/src/java/org/apache/lucene/index/IndexFileDeleter.java (working copy) @@ -134,8 +134,10 @@ this.docWriter = docWriter; this.infoStream = infoStream; + final String currentSegmentsFile = segmentInfos.getCurrentSegmentFileName(); + if (infoStream != null) - message("init: current segments file is \"" + segmentInfos.getCurrentSegmentFileName() + "\"; deletionPolicy=" + policy); + message("init: current segments file is \"" + currentSegmentsFile + "\"; deletionPolicy=" + policy); this.policy = policy; this.directory = directory; @@ -146,7 +148,6 @@ indexFilenameFilter = new IndexFileNameFilter(codecs); CommitPoint currentCommitPoint = null; - boolean seenIndexFiles = false; String[] files = null; try { files = directory.listAll(); @@ -158,7 +159,6 @@ for (String fileName : files) { if ((indexFilenameFilter.accept(null, fileName)) && !fileName.endsWith("write.lock") && !fileName.equals(IndexFileNames.SEGMENTS_GEN)) { - seenIndexFiles = true; // Add this file to refCounts with initial count 0: getRefCount(fileName); @@ -201,10 +201,7 @@ } } - // If we haven't seen any Lucene files, then currentCommitPoint is expected - // to be null, because it means it's a fresh Directory. Therefore it cannot - // be any NFS cache issues - so just ignore. - if (currentCommitPoint == null && seenIndexFiles) { + if (currentCommitPoint == null && currentSegmentsFile != null) { // We did not in fact see the segments_N file // corresponding to the segmentInfos that was passed // in. Yet, it must exist, because our caller holds @@ -214,7 +211,7 @@ // try now to explicitly open this commit point: SegmentInfos sis = new SegmentInfos(); try { - sis.read(directory, segmentInfos.getCurrentSegmentFileName(), codecs); + sis.read(directory, currentSegmentsFile, codecs); } catch (IOException e) { throw new CorruptIndexException("failed to locate current segments_N file"); } @@ -244,7 +241,7 @@ // Finally, give policy a chance to remove things on // startup: - if (seenIndexFiles) { + if (currentSegmentsFile != null) { policy.onInit(commits); }