Buggy code:
public abstract class ShardSearchingTestBase extends LuceneTestCase { public static class SearcherExpiredException extends RuntimeException { public SearcherExpiredException ( String message ) { } } private static class FieldAndShardVersion { private final long version ; private final int nodeID ; private final String field ; public FieldAndShardVersion ( int nodeID , long version , String field ) { } @ Override public int hashCode ( ) { } @ Override public boolean equals ( Object _other ) { } @ Override public String toString ( ) { } } private static class TermAndShardVersion { private final long version ; private final int nodeID ; private final Term term ; public TermAndShardVersion ( int nodeID , long version , Term term ) { } @ Override public int hashCode ( ) { } @ Override public boolean equals ( Object _other ) { } } private final String [ ] fieldsToShare = new String [ ] { "body" , "title" } ; void broadcastNodeReopen ( int nodeID , long version , IndexSearcher newSearcher ) throws IOException { } TopDocs searchNode ( int nodeID , long [ ] nodeVersions , Query q , Sort sort , int numHits , ScoreDoc searchAfter ) throws IOException { } Map < Term , TermStatistics > getNodeTermStats ( Set < Term > terms , int nodeID , long version ) throws IOException { } protected final class NodeState implements Closeable { public final Directory dir ; public final IndexWriter writer ; public final SearcherLifetimeManager searchers ; public final SearcherManager mgr ; public final int myNodeID ; public final long [ ] currentNodeVersions ; private final Map < ShardSearchingTestBase . FieldAndShardVersion , CollectionStatistics > collectionStatsCache = new ConcurrentHashMap < > ( ) ; private final Map < ShardSearchingTestBase . TermAndShardVersion , TermStatistics > termStatsCache = new ConcurrentHashMap < > ( ) ; public class ShardIndexSearcher extends IndexSearcher { public final long [ ] nodeVersions ; public final int myNodeID ; public ShardIndexSearcher ( long [ ] nodeVersions , IndexReader localReader , int nodeID ) { } @ Override public Query rewrite ( Query original ) throws IOException { } @ Override public TermStatistics termStatistics ( Term term , TermContext context ) throws IOException { } @ Override public CollectionStatistics collectionStatistics ( String field ) throws IOException { } @ Override public TopDocs search ( Query query , int numHits ) throws IOException { } public TopDocs localSearch ( Query query , int numHits ) throws IOException { } @ Override public TopDocs searchAfter ( ScoreDoc after , Query query , int numHits ) throws IOException { } public TopDocs localSearchAfter ( ScoreDoc after , Query query , int numHits ) throws IOException { } @ Override public TopFieldDocs search ( Query query , int numHits , Sort sort ) throws IOException { } public TopFieldDocs localSearch ( Query query , int numHits , Sort sort ) throws IOException { } } private volatile ShardSearchingTestBase . NodeState . ShardIndexSearcher currentShardSearcher ; public NodeState ( Random random , int nodeID , int numNodes ) throws IOException { } public void initSearcher ( long [ ] nodeVersions ) throws IOException { } public void updateNodeVersion ( int nodeID , long version ) throws IOException { } public ShardSearchingTestBase . NodeState . ShardIndexSearcher acquire ( ) { } public void release ( ShardSearchingTestBase . NodeState . ShardIndexSearcher s ) throws IOException { } public ShardSearchingTestBase . NodeState . ShardIndexSearcher acquire ( long [ ] nodeVersions ) { } public void reopen ( ) throws IOException { } @ Override public void close ( ) throws IOException { if ( ( currentShardSearcher ) != null ) { currentShardSearcher . getIndexReader ( ) . decRef ( ) ; } searchers . close ( ) ; mgr . close ( ) ; <START_BUG> writer . close ( ) ; <END_BUG> dir . close ( ) ; } } private final class ChangeIndices extends Thread { @ Override public void run ( ) { } } protected ShardSearchingTestBase . NodeState [ ] nodes ; int maxSearcherAgeSeconds ; long endTimeNanos ; private Thread changeIndicesThread ; protected void start ( int numNodes , double runTimeSec , int maxSearcherAgeSeconds ) throws IOException { } protected void finish ( ) throws IOException , InterruptedException { } protected static class SearcherAndVersion { public final IndexSearcher searcher ; public final long version ; public SearcherAndVersion ( IndexSearcher searcher , long version ) { } } }

Fix:
writer . shutdown ( ) ;