Hello,
Using Lucene 4.1.0, my application is designed to automatically run the exact
same facet search every few minutes, varying only by range on a date-time
field. However, occasionally the app fails with the below exception. Once this
occurs, all Lucene searches begin to fail - even if the problem index is
completely closed and reopened with a new searcher. Only an app restart makes
searches functional again. It can take anywhere from hours to days for this
exception to occur. I have been unable to reproduce it in the Eclipse
environment.
(Tue Apr 23 13:50:24 PST 2013) EE:ERR [LuciusDataChangeListener v0]
{null-14:202} EXCEPTION: java.lang.NullPointerException at
org.apache.lucene.search.NumericRangeQuery$NumericRangeTermsEnum.accept(NumericRangeQuery.java:526)
at org.apache.lucene.index.FilteredTermsEnum.next(FilteredTermsEnum.java:241)
at
org.apache.lucene.search.TermCollectingRewrite.collectTerms(TermCollectingRewrite.java:78)
at
org.apache.lucene.search.ConstantScoreAutoRewrite.rewrite(ConstantScoreAutoRewrite.java:95)
at
org.apache.lucene.search.MultiTermQuery$ConstantScoreAutoRewrite.rewrite(MultiTermQuery.java:220)
at org.apache.lucene.search.MultiTermQuery.rewrite(MultiTermQuery.java:286) at
org.apache.lucene.search.BooleanQuery.rewrite(BooleanQuery.java:429) at
org.apache.lucene.search.IndexSearcher.rewrite(IndexSearcher.java:616) at
org.apache.lucene.search.IndexSearcher.createNormalizedWeight(IndexSearcher.java:663)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:309)...
Note that line 526 is a call to nextRange(). But the stack trace stops there
with no indication of what might be null. Did it even make it into the
nextRange() method?
I downloaded and compiled the Lucene 4.1.0 source. I modified NumericRangeQuery
NumericRangeTermsEnum accept method to record what value is null when this
failure occurs.
protected final AcceptStatus accept(BytesRef term) { try {
while (currentUpperBound == null || termComp.compare(term, currentUpperBound) >
0) { if (rangeBounds.isEmpty()) return AcceptStatus.END;
// peek next sub-range, only seek if the current term is smaller than
next lower bound if (termComp.compare(term, rangeBounds.getFirst()) <
0) return AcceptStatus.NO_AND_SEEK; // step forward to next
range without seeking, as next lower range bound is less or equal current term
nextRange(); } return AcceptStatus.YES; } catch
(Throwable t) { String msg; if (term == null) { msg =
"term is null"; } else if (rangeBounds == null) { msg =
"rangeBounds is null"; } else if (termComp == null) { msg =
"termComp == null"; } else { msg = "we don't know what is
null!"; } throw new RuntimeException(msg, t); } } }
When the exception occurs, msg is "we don't know what is null!". So what could
possibly be null? I'm completely lost at this point.
Thoughts?-Lynn