From b7836ef3608f5e511420b0cb0e0958cc29cc6a6b Mon Sep 17 00:00:00 2001 From: David Green Date: Fri, 25 Oct 2013 18:49:40 -0700 Subject: 415140: CorruptIndexException in tasklist index Change-Id: Ia0c6ac54f23f90e32d157f5deba34b3d322aa3c4 Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=415140 --- .../internal/tasks/index/core/TaskListIndex.java | 47 +++++++++++-- .../index/tests/TaskListIndexCorruptTest.java | 76 ++++++++++++++++++++++ 2 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/TaskListIndexCorruptTest.java diff --git a/org.eclipse.mylyn.tasks.index.core/src/org/eclipse/mylyn/internal/tasks/index/core/TaskListIndex.java b/org.eclipse.mylyn.tasks.index.core/src/org/eclipse/mylyn/internal/tasks/index/core/TaskListIndex.java index 153c5df9a..861ecc614 100644 --- a/org.eclipse.mylyn.tasks.index.core/src/org/eclipse/mylyn/internal/tasks/index/core/TaskListIndex.java +++ b/org.eclipse.mylyn.tasks.index.core/src/org/eclipse/mylyn/internal/tasks/index/core/TaskListIndex.java @@ -54,6 +54,7 @@ import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; +import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.store.NIOFSDirectory; import org.apache.lucene.util.Version; @@ -1118,7 +1119,7 @@ public class TaskListIndex implements ITaskDataManagerListener, ITaskListChangeL } private void indexQueuedTasks(SubMonitor monitor) throws CorruptIndexException, LockObtainFailedException, - IOException { + IOException, CoreException { synchronized (reindexQueue) { if (reindexQueue.isEmpty()) { @@ -1148,8 +1149,17 @@ public class TaskListIndex implements ITaskDataManagerListener, ITaskListChangeL } if (writer == null) { - writer = new IndexWriter(directory, TaskAnalyzer.instance(), false, - IndexWriter.MaxFieldLength.UNLIMITED); + try { + writer = new IndexWriter(directory, TaskAnalyzer.instance(), false, + IndexWriter.MaxFieldLength.UNLIMITED); + } catch (CorruptIndexException e) { + rebuildIndex = true; + synchronized (reindexQueue) { + reindexQueue.clear(); + } + rebuildIndexCompletely(monitor); + return; + } } monitor.setWorkRemaining(workingQueue.size()); @@ -1202,8 +1212,17 @@ public class TaskListIndex implements ITaskDataManagerListener, ITaskListChangeL monitor.beginTask(Messages.TaskListIndex_task_rebuilding_index, taskListState.indexableTasks.size()); try { - final IndexWriter writer = new IndexWriter(directory, TaskAnalyzer.instance(), true, - IndexWriter.MaxFieldLength.UNLIMITED); + IndexWriter writer; + try { + writer = createIndexWriter(); + } catch (CorruptIndexException e) { + if (directory instanceof FSDirectory) { + cleanDirectory(((FSDirectory) directory).getDirectory()); + writer = createIndexWriter(); + } else { + throw e; + } + } try { for (ITask task : taskListState.indexableTasks) { @@ -1230,6 +1249,24 @@ public class TaskListIndex implements ITaskDataManagerListener, ITaskListChangeL return multiStatus; } + private void cleanDirectory(File file) throws IOException { + if (file.exists()) { + File[] children = file.listFiles(); + if (children != null) { + for (File child : children) { + if (child.isDirectory()) { + cleanDirectory(child); + } + child.delete(); + } + } + } + } + + protected IndexWriter createIndexWriter() throws CorruptIndexException, LockObtainFailedException, IOException { + return new IndexWriter(directory, TaskAnalyzer.instance(), true, IndexWriter.MaxFieldLength.UNLIMITED); + } + /** * @param writer * @param task diff --git a/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/TaskListIndexCorruptTest.java b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/TaskListIndexCorruptTest.java new file mode 100644 index 000000000..96c6c961d --- /dev/null +++ b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/TaskListIndexCorruptTest.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2013 Tasktop Technologies and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.tasks.index.tests; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Random; + +import org.eclipse.mylyn.tasks.core.ITask; +import org.junit.Test; + +public class TaskListIndexCorruptTest extends AbstractTaskListIndexTest { + + private void setupCorruptIndex() throws Exception { + setupIndex(); + context.createLocalTask(); + index.waitUntilIdle(); + + index.close(); + disposeIndex(); + + corruptIndex(); + } + + private void corruptIndex() throws IOException { + File[] files = tempDir.listFiles(); + if (files == null || files.length == 0) { + throw new IllegalStateException("index has no files"); + } + for (File file : files) { + if (file.isFile()) { + corruptFile(file); + } + } + } + + private void corruptFile(File file) throws IOException { + Random random = new Random(System.currentTimeMillis()); + long length = file.length(); + OutputStream stream = new FileOutputStream(file); + try { + byte[] bytes = new byte[1]; + for (long i = 0; i < length; ++i) { + random.nextBytes(bytes); + stream.write(bytes[0]); + } + } finally { + stream.close(); + } + } + + @Test + public void testCorrupt() throws Exception { + setupCorruptIndex(); + setupIndex(); + + ITask task = context.createLocalTask(); + + index.waitUntilIdle(); + + assertTrue(index.matches(task, task.getSummary())); + } +} -- cgit v1.2.3