主要错误信息
Exception in thread "main" java.lang.AbstractMethodError: org.apache.lucene.analysis.Analyzer.createComponents(Ljava/lang/String;)Lorg/apache/lucene/analysis/Analyzer$TokenStreamComponents;
at org.apache.lucene.analysis.Analyzer.tokenStream(Analyzer.java:162)
at com.gildata.threebody.tbm.provider.IkSegementUtils.main(IkSegementUtils.java:69)
Process finished with exit code 1
错误代码
public static void main(String[] args) throws IOException {
String text = "基于java语言开发的轻量级的中文分词工具包";
//创建分词对象
Analyzer anal = new IKAnalyzer(true);// IK实现分词 true:用最大词长分词 false:最细粒度切分
StringReader reader = new StringReader(text);
//分词
TokenStream ts = anal.tokenStream("ext_dict.dic", reader);
CharTermAttribute term = ts.getAttribute(CharTermAttribute.class);
//遍历分词数据
while (ts.incrementToken()) {
System.out.print(term.toString() + "|");
}
reader.close();
System.out.println();
}
解决办法:
主要是版本不支持,调用到最新的版本,导致的不能编译通过。这是2012年的版本;目前我们的工程 已经使用
lucene-core-7.6.0.jar
导致低版本不能支持,所以就算是去除低版本也不行,
解决1.让低版本使用,高版本剔除;
下面类似的办法只能删除高版本,使用低版本,exclusions的pom设置,下面是注释的类似哦。
<!-- https://mvnrepository.com/artifact/com.janeluo/ikanalyzer -->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
<!--<exclusions>-->
<!--<exclusion>-->
<!--<artifactId>lucene-queryparser</artifactId>-->
<!--<groupId>org.apache.lucene</groupId>-->
<!--</exclusion>-->
<!--<exclusion>-->
<!--<artifactId>lucene-core</artifactId>-->
<!--<groupId>org.apache.lucene</groupId>-->
<!--</exclusion>-->
<!--<exclusion>-->
<!--<groupId>org.slf4j</groupId>-->
<!--<artifactId>slf4j-api</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
</dependency>
解决办法2、复写低版本调用时的类,兼容高版本的入参逻辑;
复写高版本的入参
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Tokenizer;
/**
* IK分词器,Lucene Analyzer接口实现
* 兼容Lucene 7.8版本
*/
public class MyIKAnalyzer extends Analyzer {
private boolean useSmart;
public boolean useSmart() {
return useSmart;
}
public void setUseSmart(boolean useSmart) {
this.useSmart = useSmart;
}
/**
* IK分词器Lucene 7.8 Analyzer接口实现类
* <p>
* 默认细粒度切分算法
*/
public MyIKAnalyzer() {
this(false);
}
/**
* IK分词器Lucene 7.8 Analyzer接口实现类
*
* @param useSmart 当为true时,分词器进行智能切分
*/
public MyIKAnalyzer(boolean useSmart) {
super();
this.useSmart = useSmart;
}
/**
* 重载Analyzer接口,构造分词组件
*
* @param fieldName the name of the fields content passed to the
* TokenStreamComponents sink as a reader
*/
protected TokenStreamComponents createComponents(String fieldName) {
Tokenizer _IKTokenizer = new MyIKTokenizer(this.useSmart());
return new TokenStreamComponents(_IKTokenizer);
}
}
2、
public class MyIKTokenizer extends Tokenizer {
// IK分词器实现
private IKSegmenter _IKImplement;
// 词元文本属性
private final CharTermAttribute termAtt;
// 词元位移属性
private final OffsetAttribute offsetAtt;
// 词元分类属性(该属性分类参考org.wltea.analyzer.core.Lexeme中的分类常量)
private final TypeAttribute typeAtt;
// 记录最后一个词元的结束位置
private int endPosition;
/**
* Lucene 7.8 Tokenizer适配器类构造函数
* @param useSmart
*/
public MyIKTokenizer(boolean useSmart) {
super();
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
}
public boolean incrementToken() throws IOException {
// 清除所有的词元属性
clearAttributes();
Lexeme nextLexeme = _IKImplement.next();
if (nextLexeme != null) {
// 将Lexeme转成Attributes
// 设置词元文本
termAtt.append(nextLexeme.getLexemeText());
// 设置词元长度
termAtt.setLength(nextLexeme.getLength());
// 设置词元位移
offsetAtt.setOffset(nextLexeme.getBeginPosition(),
nextLexeme.getEndPosition());
// 记录分词的最后位置
endPosition = nextLexeme.getEndPosition();
// 记录词元分类
typeAtt.setType(nextLexeme.getLexemeTypeString());
// 返会true告知还有下个词元
return true;
}
// 返会false告知词元输出完毕
return false;
}
public void reset() throws IOException {
super.reset();
_IKImplement.reset(input);
}
public final void end() {
// set final offset
int finalOffset = correctOffset(this.endPosition);
offsetAtt.setOffset(finalOffset, finalOffset);
}
}