异常——org.apache.lucene.util.SetOnce$AlreadySetException

异常介绍

SetOnce

A convenient class which offers a semi-immutable object wrapper implementation which allows one to set the value of an object exactly once, and retrieve it many times.

用来封装对象的一个类,只能赋值一次,可以多次读取值,比如private SetOnce<IndexWriter> writer = new SetOnce<>();

那么writer.set(IndexWriter);只能被执行一边,哪怕是同一个IndexWriter;

AlreadySetException

If set(Object) is called more than once, SetOnce.AlreadySetException is thrown and the operation will fail.

writer.set(IndexWriter);被调用多过一次就抛这个异常。

异常出处

写了个定时更新索引的任务

TimerTask task = new Task(new Runnable() {
    public void run() { 
        index();//建索引
        indexWriter = new IndexWriter(Directory,IndexWriterConfig);//初始化已关闭的indexWriter
    }
});

异常描述

Exception in thread "main" org.apache.lucene.util.SetOnce$AlreadySetException: The object cannot be set twice!
    at org.apache.lucene.util.SetOnce.set(SetOnce.java:69)
    at org.apache.lucene.index.IndexWriterConfig.setIndexWriter(IndexWriterConfig.java:148)
    at org.apache.lucene.index.IndexWriter.<init>(IndexWriter.java:687)

原理分析

分析构造方法new IndexWriter(Directory,IndexWriterConfig);

1 public IndexWriter(Directory d, IndexWriterConfig conf) throws IOException {
2     conf.setIndexWriter(this); // prevent reuse by other instances
3     ……
4     ……
5     ……
6 }

重点在第二行conf.setIndexWriter(this);

 1 private SetOnce<IndexWriter> writer = new SetOnce<>();
 2   
 3   /**
 4    * Sets the {@link IndexWriter} this config is attached to.
 5    * 
 6    * @throws AlreadySetException
 7    *           if this config is already attached to a writer.
 8    */
 9   IndexWriterConfig setIndexWriter(IndexWriter writer) {
10     this.writer.set(writer);
11     return this;
12   }

是这样,IndexWriterConfig里的wirter变量,是用SetOnce封装的,当再用用一个IndexWriterConfig去构造IndexWriter时,writer被赋值两次所以报错了

解决办法

重新构造一个IndexWriterConfig

TimerTask task = new Task(new Runnable() {
    public void run() { 
        index();//建索引
        IndexWriterConfig config = new IndexWriterConfig(Version.Lucene_36,Analyzer);
        indexWriter = new IndexWriter(Directory,IndexWriterConfig);//初始化已关闭的indexWriter
    }
});

TO BE CONTINUED……