导致Lucene无法索引查询的NoClassDefFoundError

简介:
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,如需转载请自行联系原作者


相关文章
|
4月前
|
Java
elasticsearch在Java中查询指定列的方法
elasticsearch在Java中查询指定列的方法
86 0
|
7月前
|
SQL 数据库 索引
08Lucene索引库查询 - 介绍
08Lucene索引库查询 - 介绍
26 0
|
7月前
|
存储 自然语言处理 索引
05Lucene索引库的添加
05Lucene索引库的添加
16 0
|
7月前
|
索引
06Lucene索引库的删除
06Lucene索引库的删除
16 0
|
7月前
|
自然语言处理 索引
09 Lucene索引库查询 - query子类查询
09 Lucene索引库查询 - query子类查询
25 0
|
7月前
|
索引
07Lucene索引库的修改
07Lucene索引库的修改
16 0
|
存储 自然语言处理 关系型数据库
Lucene的查询过程
Lucene的查询过程
167 0
|
存储 自然语言处理 数据库
Lucene 查询原理
# 前言 Lucene 是一个基于 Java 的全文信息检索工具包,目前主流的搜索系统Elasticsearch和solr都是基于lucene的索引和搜索能力进行。想要理解搜索系统的实现原理,就需要深入lucene这一层,看看lucene是如何存储需要检索的数据,以及如何完成高效的数据检索。
8423 1