Buggy code:
public class TreeMergeOutputFormat extends FileOutputFormat < Text , NullWritable > { @ Override public RecordWriter getRecordWriter ( TaskAttemptContext context ) throws IOException { } private static final class TreeMergeRecordWriter extends RecordWriter < Text , NullWritable > { private final Path workDir ; private final List < Path > shards = new ArrayList ( ) ; private final HeartBeater heartBeater ; private final TaskAttemptContext context ; private static final Logger LOG = LoggerFactory . getLogger ( TreeMergeOutputFormat . TreeMergeRecordWriter . class ) ; public TreeMergeRecordWriter ( TaskAttemptContext context , Path workDir ) { } @ Override public void write ( Text key , NullWritable value ) { } @ Override public void close ( TaskAttemptContext context ) throws IOException { TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . debug ( ( ( ( ( ( "Task<seq2seq4repair_space>" + ( context . getTaskAttemptID ( ) ) ) + "<seq2seq4repair_space>merging<seq2seq4repair_space>into<seq2seq4repair_space>dstDir:<seq2seq4repair_space>" ) + ( workDir ) ) + ",<seq2seq4repair_space>srcDirs:<seq2seq4repair_space>" ) + ( shards ) ) ) ; writeShardNumberFile ( context ) ; heartBeater . needHeartBeat ( ) ; try { Directory mergedIndex = new org . apache . solr . store . hdfs . HdfsDirectory ( workDir , context . getConfiguration ( ) ) ; IndexWriterConfig writerConfig = new IndexWriterConfig ( Version . LUCENE_CURRENT , null ) . setOpenMode ( CREATE ) . setUseCompoundFile ( false ) ; if ( TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . isDebugEnabled ( ) ) { writerConfig . setInfoStream ( System . out ) ; } MergePolicy mergePolicy = writerConfig . getMergePolicy ( ) ; TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . debug ( "mergePolicy<seq2seq4repair_space>was:<seq2seq4repair_space>{}" , mergePolicy ) ; if ( mergePolicy instanceof TieredMergePolicy ) { ( ( TieredMergePolicy ) ( mergePolicy ) ) . setNoCFSRatio ( 0.0 ) ; } else if ( mergePolicy instanceof LogMergePolicy ) { ( ( LogMergePolicy ) ( mergePolicy ) ) . setNoCFSRatio ( 0.0 ) ; } TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . info ( "Using<seq2seq4repair_space>mergePolicy:<seq2seq4repair_space>{}" , mergePolicy ) ; IndexWriter writer = new IndexWriter ( mergedIndex , writerConfig ) ; Directory [ ] indexes = new Directory [ shards . size ( ) ] ; for ( int i = 0 ; i < ( shards . size ( ) ) ; i ++ ) { indexes [ i ] = new org . apache . solr . store . hdfs . HdfsDirectory ( shards . get ( i ) , context . getConfiguration ( ) ) ; } context . setStatus ( ( ( "Logically<seq2seq4repair_space>merging<seq2seq4repair_space>" + ( shards . size ( ) ) ) + "<seq2seq4repair_space>shards<seq2seq4repair_space>into<seq2seq4repair_space>one<seq2seq4repair_space>shard" ) ) ; TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . info ( ( ( ( "Logically<seq2seq4repair_space>merging<seq2seq4repair_space>" + ( shards . size ( ) ) ) + "<seq2seq4repair_space>shards<seq2seq4repair_space>into<seq2seq4repair_space>one<seq2seq4repair_space>shard:<seq2seq4repair_space>" ) + ( workDir ) ) ) ; long start = System . nanoTime ( ) ; writer . addIndexes ( indexes ) ; if ( TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . isDebugEnabled ( ) ) { context . getCounter ( SolrCounters . class . getName ( ) , LOGICAL_TREE_MERGE_TIME . toString ( ) ) . increment ( ( ( System . currentTimeMillis ( ) ) - start ) ) ; } float secs = ( ( System . nanoTime ( ) ) - start ) // ( ( float ) ( 10 ^ 9 ) ) ; TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . info ( "Logical<seq2seq4repair_space>merge<seq2seq4repair_space>took<seq2seq4repair_space>{}<seq2seq4repair_space>secs" , secs ) ; int maxSegments = context . getConfiguration ( ) . getInt ( MAX_SEGMENTS_ON_TREE_MERGE , Integer . MAX_VALUE ) ; context . setStatus ( ( ( "Optimizing<seq2seq4repair_space>Solr:<seq2seq4repair_space>forcing<seq2seq4repair_space>mtree<seq2seq4repair_space>merge<seq2seq4repair_space>down<seq2seq4repair_space>to<seq2seq4repair_space>" + maxSegments ) + "<seq2seq4repair_space>segments" ) ) ; TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . info ( "Optimizing<seq2seq4repair_space>Solr:<seq2seq4repair_space>forcing<seq2seq4repair_space>tree<seq2seq4repair_space>merge<seq2seq4repair_space>down<seq2seq4repair_space>to<seq2seq4repair_space>{}<seq2seq4repair_space>segments" , maxSegments ) ; start = System . nanoTime ( ) ; if ( maxSegments < ( Integer . MAX_VALUE ) ) { writer . forceMerge ( maxSegments ) ; } if ( TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . isDebugEnabled ( ) ) { context . getCounter ( SolrCounters . class . getName ( ) , PHYSICAL_TREE_MERGE_TIME . toString ( ) ) . increment ( ( ( System . currentTimeMillis ( ) ) - start ) ) ; } secs = ( ( System . nanoTime ( ) ) - start ) // ( ( float ) ( 10 ^ 9 ) ) ; TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . info ( "Optimizing<seq2seq4repair_space>Solr:<seq2seq4repair_space>done<seq2seq4repair_space>forcing<seq2seq4repair_space>tree<seq2seq4repair_space>merge<seq2seq4repair_space>down<seq2seq4repair_space>to<seq2seq4repair_space>{}<seq2seq4repair_space>segments<seq2seq4repair_space>in<seq2seq4repair_space>{}<seq2seq4repair_space>secs" , maxSegments , secs ) ; start = System . nanoTime ( ) ; TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . info ( "Optimizing<seq2seq4repair_space>Solr:<seq2seq4repair_space>Closing<seq2seq4repair_space>index<seq2seq4repair_space>writer" ) ; <START_BUG> writer . close ( ) ; <END_BUG> secs = ( ( System . nanoTime ( ) ) - start ) // ( ( float ) ( 10 ^ 9 ) ) ; TreeMergeOutputFormat . TreeMergeRecordWriter . LOG . info ( "Optimizing<seq2seq4repair_space>Solr:<seq2seq4repair_space>Done<seq2seq4repair_space>closing<seq2seq4repair_space>index<seq2seq4repair_space>writer<seq2seq4repair_space>in<seq2seq4repair_space>{}<seq2seq4repair_space>secs" , secs ) ; context . setStatus ( "Done" ) ; } finally { heartBeater . cancelHeartBeat ( ) ; heartBeater . close ( ) ; } } private void writeShardNumberFile ( TaskAttemptContext context ) throws IOException { } } }

Fix:
writer . shutdown ( ) ;