Hi there

It appears my Lucene 2.3.1 index is corrupted. I get the following error when searching:

/mnt/indexnew/_3wk0.cfs (No such file or directory)
java.io.FileNotFoundException: /mnt/indexnew/_3wk0.cfs (No such file or directory)
       at java.io.RandomAccessFile.open(Native Method)
       at java.io.RandomAccessFile.<init>(RandomAccessFile.java:231)
at org.apache.lucene.store.FSDirectory$FSIndexInput$Descriptor.<init>(FSDirectory.java:506) at org.apache.lucene.store.FSDirectory$FSIndexInput.<init>(FSDirectory.java:536) at org.apache.lucene.store.FSDirectory.openInput(FSDirectory.java:445) at org.apache.lucene.index.CompoundFileReader.<init>(CompoundFileReader.java:70) at org.apache.lucene.index.SegmentReader.initialize(SegmentReader.java:277)
       at org.apache.lucene.index.SegmentReader.get(SegmentReader.java:262)
       at org.apache.lucene.index.SegmentReader.get(SegmentReader.java:197)
at org.apache.lucene.index.MultiSegmentReader.<init>(MultiSegmentReader.java:55) at org.apache.lucene.index.DirectoryIndexReader$1.doBody(DirectoryIndexReader.java:75) at org.apache.lucene.index.SegmentInfos$FindSegmentsFile.run(SegmentInfos.java:636) at org.apache.lucene.index.DirectoryIndexReader.open(DirectoryIndexReader.java:63)
       at org.apache.lucene.index.IndexReader.open(IndexReader.java:209)
       at org.apache.lucene.index.IndexReader.open(IndexReader.java:173)
at org.apache.lucene.search.IndexSearcher.<init>(IndexSearcher.java:48)
       at

Question #1: How can I recover from this error without regenerating the entire index?

Is there a utility I could use?

Question #2: What is the reason why I am missing a segument cfs file?

Could it be a problem with the synchronization of threads during Indexing (see attached code)?
Could it be a bug in MailArchiva?
I have tried to implement locks in appropriate places.
java.io.FileNotFoundException: /mnt/indexnew/_3wk0.cfs (No such file or directory)

Any help would be much appreciated!

Jamie

package com.stimulus.archiva.index;

/* Copyright (C) 2005-2007 Jamie Angus Band 
 * MailArchiva Open Source Edition Copyright (c) 2005-2007 Jamie Angus Band
 * This program is free software; you can redistribute it and/or modify it 
under the terms of
 * the GNU General Public License as published by the Free Software Foundation; 
either version
 * 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with 
this program;
 * if not, see http://www.gnu.org/licenses or write to the Free Software 
Foundation,Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 */


import javax.mail.*;
import javax.mail.internet.*;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import com.ice.tar.*;
import org.apache.log4j.Logger;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.store.*;
import com.stimulus.archiva.domain.*;
import com.stimulus.archiva.exception.*;
import com.stimulus.archiva.language.*;
import com.stimulus.archiva.extraction.*;
import com.stimulus.archiva.search.*;
import com.stimulus.util.TempFiles;
import com.stimulus.archiva.domain.fields.*;
import com.stimulus.util.*;
import java.nio.charset.Charset;
import org.apache.log4j.Level;

public class MessageIndex extends Indexer implements Serializable {
        
          
          private static final long serialVersionUID = -17692874371162272L;
          protected static final Logger logger = 
Logger.getLogger(MessageIndex.class.getName());
          protected static int INDEX_WAIT_PERIOD = 50;
          protected static int DEAD_PERIOD = 300000000;
          protected boolean shutdown = false;
          static Hashtable<Volume,VolumeIndex> volumeIndexes = new 
Hashtable<Volume,VolumeIndex>();
          static Object volumeIndexLock = new Object();
 
    public MessageIndex() {
          
    }
 

        public void deleteIndex(Volume volume) throws MessageSearchException {
                  VolumeIndex volumeIndex = getVolumeIndex(volume);
                  volumeIndex.deleteIndex();
        }
                 
        
        public VolumeIndex getVolumeIndex(Volume volume) {
                 VolumeIndex volumeIndex = null;
                  synchronized (volumeIndexLock) {
                          volumeIndex = volumeIndexes.get(volume);
                          if (volumeIndex==null) {
                                  volumeIndex = new VolumeIndex(this,volume);
                                  volumeIndexes.put(volume,volumeIndex);
                          }
                  }
                  return volumeIndex;
        }
                
        public void indexMessage(Email email) throws MessageSearchException {
                  VolumeIndex volumeIndex = 
getVolumeIndex(email.getEmailId().getVolume());
                  volumeIndex.indexMessage(email);
        }
                
                
                  // Enterprise version
          
        public void deleteMessage(EmailID emailID) throws 
MessageSearchException {
                  if (emailID == null)
                    throw new MessageSearchException("assertion failure: null 
emailID",logger);
          logger.debug("delete message {'"+emailID+"'}");
          Volume volume = emailID.getVolume();
          File indexDir = new File(volume.getIndexPath());
          if (!indexDir.exists())
                  throw new MessageSearchException("could not delete email from 
index. volume does not exist. {'"+emailID+"}",logger);
          IndexReader indexReader = null;
          try {
                  indexReader = IndexReader.open(indexDir);
          } catch (IOException e ) {
                  throw new MessageSearchException("failed to open index to 
delete email",e,logger);
          }
          try {
                  indexReader.deleteDocuments(new 
Term("uid",emailID.getUniqueID()));
                  indexReader.close();
          } catch (Exception e) {
                  throw new MessageSearchException("failed to delete email from 
index.",e,logger);
          }
        }
          
        public void prepareIndex(Volume volume) throws MessageSearchException {
                        
                  if (volume==null)
                            throw new MessageSearchException("assertion 
failure: null volume",logger);
        
          if (volume.getIndexPath().startsWith("rmi://"))
                          return;
                          
          File indexDir = new File(volume.getIndexPath());
          if (!indexDir.exists()) {
                logger.info("index directory does not exist. will proceed with 
creation {location='" + volume.getIndexPath() + "'}");
                boolean success = indexDir.mkdir();
                if (!success)
                                throw new MessageSearchException("failed to 
create index directory {location='" + volume.getIndexPath() + "'}",logger);
                logger.info("index directory successfully created {location='" 
+ volume.getIndexPath() + "'}");
                  }
        
        }
          
        protected void finalize() throws Throwable {
            logger.debug("messagindex class is shutting down");
            try {
                shutdown = true;
            } finally {
                super.finalize();
            }
        }

}
package com.stimulus.archiva.index;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import javax.mail.MessagingException;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.*;
import org.apache.lucene.store.FSDirectory;
import com.stimulus.archiva.domain.Config;
import com.stimulus.archiva.domain.Email;
import com.stimulus.archiva.domain.Indexer;
import com.stimulus.archiva.domain.Volume;
import com.stimulus.archiva.exception.ExtractionException;
import com.stimulus.archiva.exception.MessageSearchException;
import com.stimulus.archiva.language.AnalyzerFactory;
import com.stimulus.archiva.search.*;
import java.util.*;
import org.apache.lucene.store.AlreadyClosedException;

public class VolumeIndex {
        
                 protected static final Logger logger = 
Logger.getLogger(VolumeIndex.class.getName());
                 public static final int indexOpenTime = 2000;
                 IndexWriter writer = null;
                 Volume volume;
                 Timer closeIndexTimer = new Timer();
                 Object indexLock = new Object();
                
                 
                 ArchivaAnalyzer analyzer       = new ArchivaAnalyzer();
                 Indexer indexer = null;
                  public VolumeIndex(Indexer indexer, Volume volume) {
                                this.volume = volume;
                                this.indexer = indexer;
                                closeIndexTimer.scheduleAtFixedRate(new 
TimerTask() {
                            public void run() {
                                closeIndex();
                            }
                        }, indexOpenTime, indexOpenTime);
                  }

                  protected void openIndex(boolean retry) throws 
MessageSearchException {
                         Exception lastError = null;
                         synchronized(indexLock) {
                        if (writer==null) {
                                logger.debug("openIndex() index will be opened. 
it is currently closed.");
                        } else {
                                logger.debug("openIndex() did not bother 
opening index. it is already open.");
                                return; 
                        }

                                logger.debug("opening index for write 
{"+volume+"}");
                                indexer.prepareIndex(volume);
                                logger.debug("opening search index for write 
{indexpath='"+volume.getIndexPath()+"'}");
                        
                                try {
                                                writer = new 
IndexWriter(FSDirectory.getDirectory(volume.getIndexPath()),false, analyzer);
                                                writer.setMaxFieldLength(50000);
                                                if (logger.isDebugEnabled()) {
                                                        File file = new 
File(Config.getFileSystem().getLogPath()+File.separator+"index.log");
                                                        PrintStream debugout = 
new PrintStream(file);
                                                        
writer.setInfoStream(debugout);
                                                }
                                } catch (IOException io) {
                                        lastError = io;
                                        if (!retry) {
                                                // most obvious reason for 
error is that there is a lock on the index, due hard shutdown
                                                    // resolution delete the 
lock, and try again
                                                    logger.warn("failed to open 
search index for write. possible write lock due to hard system shutdown.",io);
                                                    logger.info("attempting 
recovery. deleting index lock file and retrying..");
                                                    File lockFile = new 
File(volume.getIndexPath()+File.separatorChar + "write.lock");
                                                    lockFile.delete();
                                                    openIndex(true);
                                        } else {
                                                throw new 
MessageSearchException("failed to open/ index writer 
{location='"+volume.getIndexPath()+"'}",lastError,logger);
                                        }
                                }
                        }
                }
                
                public void indexMessage(Email message) throws 
MessageSearchException  {
      
                        long s = (new Date()).getTime();
                        if (message == null)
                            throw new MessageSearchException("assertion 
failure: null message",logger);
                        logger.debug("indexing message {"+message+"}");
                        
                        Document doc = new Document();
                        try {
                         
                           DocumentIndex docIndex = new DocumentIndex(indexer);
                           docIndex.write(message,doc);  
                           String language = doc.get("lang");
                           if (language==null)
                                   language = indexer.getIndexLanguage();
                                synchronized (indexLock) {
                                        openIndex(false);
                                        
writer.addDocument(doc,AnalyzerFactory.getAnalyzer(language,AnalyzerFactory.Operation.INDEX));
                                }
                                doc = null;
                           logger.debug("message indexed successfully 
{"+message+",language='"+language+"'}");
                        } catch (MessagingException me)
                        {
                           throw new MessageSearchException("failed to decode 
message during indexing",me,logger, Level.DEBUG);
                        } catch (IOException me) {
                            throw new MessageSearchException("failed to index 
message {"+message+"}",me,logger, Level.DEBUG);
                        } catch (ExtractionException ee)
                        {
                                // we will want to continue indexing
                           //throw new MessageSearchException("failed to decode 
attachments in message {"+message+"}",ee,logger, Level.DEBUG);
                        } catch (AlreadyClosedException ace) {
                                indexMessage(message);
                        } catch (Exception e) {
                            throw new MessageSearchException("failed to index 
message",e,logger, Level.DEBUG);
                        }
                        logger.debug("indexing message end {"+message+"}");
                        
                        long e = (new Date()).getTime();
                    logger.debug("indexing time {time='"+(e-s)+"'}");
                }
                        
                protected void closeIndex() {
                
                           synchronized(indexLock) {
                                if (writer==null)
                                                return;
                                try {
                                        writer.close();
                                            logger.debug("writer closed");
                                        } catch (Exception io) {
                                                logger.error("failed to close 
index writer:"+io.getMessage(),io);
        
                                        }
                                writer = null;
                                }
                }
                 //      deliberately non recursive (so we avoid situations 
where the whole h/d is deleted)
                  public void deleteIndex() throws MessageSearchException {
                          logger.debug("delete index 
{indexpath='"+volume.getIndexPath()+"'}");
                         
                                try {
                                          writer = new 
IndexWriter(FSDirectory.getDirectory(volume.getIndexPath()),false, 
analyzer,true);
                                } catch (Exception cie) {
                                         logger.error("failed to delete index 
{index='"+volume.getIndexPath()+"'}",cie);
                                         File indexDir = new 
File(volume.getIndexPath());
                         if (!indexDir.exists()) return;
                         if (indexDir.isDirectory()) {
                            String[] children = indexDir.list();
                            for (int i=0; i<children.length; i++) {
                                String filepath = 
volume.getIndexPath()+File.separatorChar+children[i];
                                logger.debug("deleting file {path='" + filepath 
+"'}");
                                File file = new File(filepath);
                                boolean success = file.delete();
                                if (!success) {
                                        try {
                                                File newFile = 
File.createTempFile("temp","idx");
                                                file.renameTo(newFile);
                                        } catch (Exception e2) {
                                                throw new 
MessageSearchException("failed to delete file in existing index 
{filepath='"+filepath+"'}",logger);
                                        }
                                } else
                                   logger.debug("deleted file successfully 
{filepath='" + filepath +"'}");
                            }
                         }
                         return;
                                }
                                try {
                                  writer.close();
                } catch (Exception e) {
                        logger.error("failed to delete index 
{index='"+volume.getIndexPath()+"'}",e);
                }
             
                MessageIndex.volumeIndexes.remove(this);
              

                  }
                
                protected void finalize() throws Throwable {
                    logger.debug("volumeindex class is shutting down");
                    try {
                        closeIndexTimer.cancel();
                        closeIndex();
                    } finally {
                        super.finalize();
                    }
                }
                
}

        


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to