Lucene 2.9.2: AlreadyClosedException at instantiation of IndexSearcher
Context:
A helper facade class is providing search methods for my application. As performance is not an issue, a newIndexSearcher
is created for each query.
For each query, a new searcher is created like this:
File indexFile = new File(String absolutePathToIndex);
IndexSearcher searcher = new IndexSearcher(indexFile.getAbsolutePath(), true);
Sometimes I get the A开发者_JAVA百科lreadyClosedException
which I do not understand because there is no sharing of the searcher object.
Any ideas? Any best practice of how to open the index? Known issues? Thanks.
Stacktrace:
org.apache.lucene.store.AlreadyClosedException: this Directory is closed
at org.apache.lucene.store.Directory.ensureOpen(Directory.java:251)
at org.apache.lucene.store.FSDirectory.listAll(FSDirectory.java:530)
at org.apache.lucene.index.SegmentInfos$FindSegmentsFile.run(SegmentInfos.java:585)
at org.apache.lucene.index.DirectoryReader.open(DirectoryReader.java:69)
at org.apache.lucene.index.IndexReader.open(IndexReader.java:476)
at org.apache.lucene.index.IndexReader.open(IndexReader.java:243)
at org.apache.lucene.search.IndexSearcher.<init>(IndexSearcher.java:78)
Proposed Solution #1: the way to go?
Directory directory = FSDirectory.open(File indexFile);
IndexSearcher searcher = new IndexSearcher(directory, true);
...do the query...
searcher.close();
Question: the above code from solution #1 is created for EACH query. Is it necessary to close the directory too? Having checked the source code of Lucene 2.9.2, searcher.close()
does not close the directory
associated with the internal reader
object.
The method which you call in this example is anyways deprecated. So maybe the use of the IndexSearcher(Directory path, boolean readOnly)
shows up a different behavior.
You need to make sure that you dont close the Directory before every subsequent search finishes. So for example if you use this Directory multiple times and you reinstantiate the Searcher the other Searcher will be destroyed and probably close the Directory in the destructor.
So if you use already the not deprecated version of the ctor try to use a new Directory instance per Searcher.
With newer versions of Lucene, I recommend using the SearcherManager
helper class, which ends up hiding all of the concurrency/locking and lifecycle steps that you'd have to otherwise implement yourself.
A basic tutorial from Mike McCandless, a Lucene project comitter: http://blog.mikemccandless.com/2011/09/lucenes-searchermanager-simplifies.html
If an error only happens under high concurrent load, it suggests that perhaps you have multiple threads attempting to close the directory Or trying to read from already closed directory. You haven't clarified whether absolutePath
is a local variable inside a method, or an instance variable in an object which is getting reused by multiple
threads -- so it's hard to guess.
精彩评论