Lucene乃是當今免費開源搜尋引擎的霸主,确實它十分好用,發展勢頭也很生猛,在Apache組織的支援下不斷的更新、推出新版本。
但是其存在一個隐藏的很深的bug,相信困擾了不少和我一樣研究使用過它的人,這個bug從早期的版本到目前的V2.3.1一個存在,不能不說是一個遺憾。
具體觸發這個bug的原因很複雜,在某些環境、伺服器、應用中……
表現為建立索引檔案和執行查詢時報“NoClassDefFoundError”,跟進代碼會發現是“SegmentReader”這個類型不能建立執行個體,但怎麼看這個類都是存在的。其實問題在這(SegmentReader.java):
/** *//** The class which implements SegmentReader. */
private static Class IMPL;
static ...{
try ...{
String name =
System.getProperty("org.apache.lucene.SegmentReader.class",
SegmentReader.class.getName());
IMPL = Class.forName(name);
} catch (ClassNotFoundException e) ...{
throw new RuntimeException("cannot load SegmentReader class: " + e, e);
} catch (SecurityException se) ...{
try ...{
IMPL = Class.forName(SegmentReader.class.getName());
} catch (ClassNotFoundException e) ...{
throw new RuntimeException("cannot load default SegmentReader class: " + e, e);
}
}
}
看到這句沒有“System.getProperty("org.apache.lucene.SegmentReader.class", SegmentReader.class.getName());”,鬼知道它什麼時候把這個系統屬性設入記憶體中的!它的本意是想動态加載SegmentReader,但反而有可能弄巧成拙,導緻Class.forName報出NoClassDefFoundError,更要命的是在static{}代碼段中的Error不會明确的顯示在異常堆棧中,任你用什麼debug手段都不能立即定位問題。
知道了問題,最簡單的解決方法,很直接,改代碼。把那個IMPL和static{}段幹脆去掉,不利用系統屬性動态加載就是了,就直接使用SegmentReader,就認準它了:-)
本文轉自胡奇 51CTO部落格,原文連結:http://blog.51cto.com/huqicto/280972,如需轉載請自行聯系原作者