Index: modules/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTLookup.java =================================================================== --- modules/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTLookup.java (revision 1127872) +++ modules/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTLookup.java (working copy) @@ -510,7 +510,7 @@ this.automaton = new FST(new InputStreamDataInput(is), NoOutputs.getSingleton()); cacheRootArcs(); } finally { - IOUtils.closeSafely(is); + IOUtils.closeSafely(false, is); } return true; } @@ -532,7 +532,7 @@ try { this.automaton.save(new OutputStreamDataOutput(os)); } finally { - IOUtils.closeSafely(os); + IOUtils.closeSafely(false, os); } return true; Index: lucene/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (revision 1127872) +++ lucene/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (working copy) @@ -919,7 +919,7 @@ assertTrue(failure.failOnCommit && failure.failOnDeleteFile); w.rollback(); assertFalse(dir.fileExists("1.fnx")); - // FIXME: on windows, this often fails! assertEquals(0, dir.listAll().length); + assertEquals(0, dir.listAll().length); dir.close(); } } Index: lucene/src/java/org/apache/lucene/index/DocInverterPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocInverterPerField.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/DocInverterPerField.java (working copy) @@ -53,8 +53,11 @@ @Override void abort() { - consumer.abort(); - endConsumer.abort(); + try { + consumer.abort(); + } finally { + endConsumer.abort(); + } } @Override Index: lucene/src/java/org/apache/lucene/index/FieldsWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/FieldsWriter.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/FieldsWriter.java (working copy) @@ -80,7 +80,7 @@ success = true; } finally { if (!success) { - abort(); + IOUtils.closeSafely(true, fieldsStream, indexStream); } } } @@ -113,7 +113,7 @@ void close() throws IOException { if (directory != null) { try { - IOUtils.closeSafely(fieldsStream, indexStream); + IOUtils.closeSafely(false, fieldsStream, indexStream); } finally { fieldsStream = indexStream = null; } Index: lucene/src/java/org/apache/lucene/index/CompoundFileWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/CompoundFileWriter.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/CompoundFileWriter.java (working copy) @@ -219,7 +219,7 @@ } catch (IOException e) { priorException = e; } finally { - IOUtils.closeSafely(priorException, os); + IOUtils.closeSafelyPriorEx(priorException, os); } } Index: lucene/src/java/org/apache/lucene/index/SegmentInfos.java =================================================================== --- lucene/src/java/org/apache/lucene/index/SegmentInfos.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/SegmentInfos.java (working copy) @@ -40,6 +40,7 @@ import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexOutput; import org.apache.lucene.store.NoSuchDirectoryException; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.ThreadInterruptedException; /** @@ -323,18 +324,14 @@ SegmentInfosWriter infosWriter = codecs.getSegmentInfosWriter(); segnOutput = infosWriter.writeInfos(directory, segmentFileName, this); infosWriter.prepareCommit(segnOutput); - success = true; pendingSegnOutput = segnOutput; + success = true; } finally { if (!success) { // We hit an exception above; try to close the file // but suppress any exception: + IOUtils.closeSafely(true, segnOutput); try { - segnOutput.close(); - } catch (Throwable t) { - // Suppress so we keep throwing the original exception - } - try { // Try not to leave a truncated segments_N file in // the index: directory.deleteFile(segmentFileName); Index: lucene/src/java/org/apache/lucene/index/TermsHash.java =================================================================== --- lucene/src/java/org/apache/lucene/index/TermsHash.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/TermsHash.java (working copy) @@ -54,7 +54,6 @@ final boolean trackAllocations; - public TermsHash(final DocumentsWriterPerThread docWriter, final TermsHashConsumer consumer, boolean trackAllocations, final TermsHash nextTermsHash) { this.docState = docWriter.docState; this.docWriter = docWriter; @@ -134,12 +133,9 @@ @Override void finishDocument() throws IOException { - try { - consumer.finishDocument(this); - } finally { - if (nextTermsHash != null) { - nextTermsHash.consumer.finishDocument(nextTermsHash); - } + consumer.finishDocument(this); + if (nextTermsHash != null) { + nextTermsHash.consumer.finishDocument(nextTermsHash); } } Index: lucene/src/java/org/apache/lucene/index/SegmentMerger.java =================================================================== --- lucene/src/java/org/apache/lucene/index/SegmentMerger.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/SegmentMerger.java (working copy) @@ -34,6 +34,7 @@ import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexOutput; import org.apache.lucene.util.Bits; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.MultiBits; import org.apache.lucene.util.ReaderUtil; @@ -546,14 +547,13 @@ } codec = segmentWriteState.segmentCodecs.codec(); final FieldsConsumer consumer = codec.fieldsConsumer(segmentWriteState); - - // NOTE: this is silly, yet, necessary -- we create a - // MultiBits as our skip docs only to have it broken - // apart when we step through the docs enums in - // MultiDocsEnum. - mergeState.multiDeletedDocs = new MultiBits(bits, bitsStarts); - try { + // NOTE: this is silly, yet, necessary -- we create a + // MultiBits as our skip docs only to have it broken + // apart when we step through the docs enums in + // MultiDocsEnum. + mergeState.multiDeletedDocs = new MultiBits(bits, bitsStarts); + consumer.merge(mergeState, new MultiFields(fields.toArray(Fields.EMPTY_ARRAY), slices.toArray(ReaderUtil.Slice.EMPTY_ARRAY))); @@ -579,6 +579,7 @@ private void mergeNorms() throws IOException { IndexOutput output = null; + boolean success = false; try { for (FieldInfo fi : fieldInfos) { if (fi.isIndexed && !fi.omitNorms) { @@ -612,10 +613,9 @@ } } } + success = true; } finally { - if (output != null) { - output.close(); - } + IOUtils.closeSafely(!success, output); } } } Index: lucene/src/java/org/apache/lucene/index/DocFieldProcessor.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocFieldProcessor.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/DocFieldProcessor.java (working copy) @@ -84,20 +84,45 @@ @Override public void abort() { - for(int i=0;i it = consumers.iterator(); - IOException err = null; + Throwable th = null; while (it.hasNext()) { try { it.next().close(); - } catch (IOException ioe) { - // keep first IOException we hit but keep - // closing the rest - if (err == null) { - err = ioe; + } catch (Throwable t) { + // keep first error we hit but keep closing the rest + if (th == null) { + th = t; } } } - if (err != null) { - throw err; + + if (th != null) { + if (th instanceof IOException) throw (IOException) th; + if (th instanceof RuntimeException) throw (RuntimeException) th; + if (th instanceof Error) throw (Error) th; + throw new RuntimeException(th); } } } @@ -177,21 +184,24 @@ @Override public void close() throws IOException { + // TODO: use IOUtils.closeSafely Iterator it = codecs.values().iterator(); - IOException err = null; + Throwable th = null; while (it.hasNext()) { try { it.next().close(); - } catch (IOException ioe) { - // keep first IOException we hit but keep - // closing the rest - if (err == null) { - err = ioe; + } catch (Throwable t) { + // keep first error we hit but keep closing the rest + if (th == null) { + th = t; } } } - if (err != null) { - throw err; + if (th != null) { + if (th instanceof IOException) throw (IOException) th; + if (th instanceof RuntimeException) throw (RuntimeException) th; + if (th instanceof Error) throw (Error) th; + throw new RuntimeException(th); } } Index: lucene/src/java/org/apache/lucene/index/TermVectorsWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/TermVectorsWriter.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/TermVectorsWriter.java (working copy) @@ -31,15 +31,22 @@ private FieldInfos fieldInfos; public TermVectorsWriter(Directory directory, String segment, - FieldInfos fieldInfos) - throws IOException { - // Open files for TermVector storage - tvx = directory.createOutput(IndexFileNames.segmentFileName(segment, "", IndexFileNames.VECTORS_INDEX_EXTENSION)); - tvx.writeInt(TermVectorsReader.FORMAT_CURRENT); - tvd = directory.createOutput(IndexFileNames.segmentFileName(segment, "", IndexFileNames.VECTORS_DOCUMENTS_EXTENSION)); - tvd.writeInt(TermVectorsReader.FORMAT_CURRENT); - tvf = directory.createOutput(IndexFileNames.segmentFileName(segment, "", IndexFileNames.VECTORS_FIELDS_EXTENSION)); - tvf.writeInt(TermVectorsReader.FORMAT_CURRENT); + FieldInfos fieldInfos) throws IOException { + boolean success = false; + try { + // Open files for TermVector storage + tvx = directory.createOutput(IndexFileNames.segmentFileName(segment, "", IndexFileNames.VECTORS_INDEX_EXTENSION)); + tvx.writeInt(TermVectorsReader.FORMAT_CURRENT); + tvd = directory.createOutput(IndexFileNames.segmentFileName(segment, "", IndexFileNames.VECTORS_DOCUMENTS_EXTENSION)); + tvd.writeInt(TermVectorsReader.FORMAT_CURRENT); + tvf = directory.createOutput(IndexFileNames.segmentFileName(segment, "", IndexFileNames.VECTORS_FIELDS_EXTENSION)); + tvf.writeInt(TermVectorsReader.FORMAT_CURRENT); + success = true; + } finally { + if (!success) { + IOUtils.closeSafely(true, tvx, tvd, tvf); + } + } this.fieldInfos = fieldInfos; } @@ -51,8 +58,7 @@ * @param vectors * @throws IOException */ - public final void addAllDocVectors(TermFreqVector[] vectors) - throws IOException { + public final void addAllDocVectors(TermFreqVector[] vectors) throws IOException { tvx.writeLong(tvd.getFilePointer()); tvx.writeLong(tvf.getFilePointer()); @@ -187,6 +193,6 @@ final void close() throws IOException { // make an effort to close all streams we can but remember and re-throw // the first exception encountered in this process - IOUtils.closeSafely(tvx, tvd, tvf); + IOUtils.closeSafely(false, tvx, tvd, tvf); } } Index: lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingCodec.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingCodec.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingCodec.java (working copy) @@ -38,6 +38,7 @@ import org.apache.lucene.index.codecs.TermsIndexWriterBase; import org.apache.lucene.index.codecs.standard.StandardCodec; import org.apache.lucene.store.Directory; +import org.apache.lucene.util.IOUtils; /** This codec "inlines" the postings for terms that have * low docFreq. It wraps another codec, which is used for @@ -81,7 +82,7 @@ success = true; } finally { if (!success) { - pulsingWriter.close(); + IOUtils.closeSafely(true, pulsingWriter); } } @@ -93,11 +94,7 @@ return ret; } finally { if (!success) { - try { - pulsingWriter.close(); - } finally { - indexWriter.close(); - } + IOUtils.closeSafely(true, pulsingWriter, indexWriter); } } } Index: lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java (working copy) @@ -71,8 +71,6 @@ * for this term) is <= maxPositions, then the postings are * inlined into terms dict */ public PulsingPostingsWriterImpl(int maxPositions, PostingsWriterBase wrappedPostingsWriter) throws IOException { - super(); - pending = new Position[maxPositions]; for(int i=0;i