mirror of https://github.com/apache/lucene.git
LUCENE-1331: catch if FSDirectory is used after being closed
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@675485 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
74c551fb88
commit
a9ce6fd334
|
@ -38,6 +38,8 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
public abstract class Directory {
|
public abstract class Directory {
|
||||||
|
|
||||||
|
volatile boolean isOpen = true;
|
||||||
|
|
||||||
/** Holds the LockFactory instance (implements locking for
|
/** Holds the LockFactory instance (implements locking for
|
||||||
* this Directory instance). */
|
* this Directory instance). */
|
||||||
protected LockFactory lockFactory;
|
protected LockFactory lockFactory;
|
||||||
|
@ -210,4 +212,12 @@ public abstract class Directory {
|
||||||
if(closeDirSrc)
|
if(closeDirSrc)
|
||||||
src.close();
|
src.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws AlreadyClosedException if this Directory is closed
|
||||||
|
*/
|
||||||
|
protected final void ensureOpen() throws AlreadyClosedException {
|
||||||
|
if (!isOpen)
|
||||||
|
throw new AlreadyClosedException("this Directory is closed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,17 +317,20 @@ public class FSDirectory extends Directory {
|
||||||
|
|
||||||
/** Returns an array of strings, one for each Lucene index file in the directory. */
|
/** Returns an array of strings, one for each Lucene index file in the directory. */
|
||||||
public String[] list() {
|
public String[] list() {
|
||||||
|
ensureOpen();
|
||||||
return directory.list(IndexFileNameFilter.getFilter());
|
return directory.list(IndexFileNameFilter.getFilter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true iff a file with the given name exists. */
|
/** Returns true iff a file with the given name exists. */
|
||||||
public boolean fileExists(String name) {
|
public boolean fileExists(String name) {
|
||||||
|
ensureOpen();
|
||||||
File file = new File(directory, name);
|
File file = new File(directory, name);
|
||||||
return file.exists();
|
return file.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the time the named file was last modified. */
|
/** Returns the time the named file was last modified. */
|
||||||
public long fileModified(String name) {
|
public long fileModified(String name) {
|
||||||
|
ensureOpen();
|
||||||
File file = new File(directory, name);
|
File file = new File(directory, name);
|
||||||
return file.lastModified();
|
return file.lastModified();
|
||||||
}
|
}
|
||||||
|
@ -340,18 +343,21 @@ public class FSDirectory extends Directory {
|
||||||
|
|
||||||
/** Set the modified time of an existing file to now. */
|
/** Set the modified time of an existing file to now. */
|
||||||
public void touchFile(String name) {
|
public void touchFile(String name) {
|
||||||
|
ensureOpen();
|
||||||
File file = new File(directory, name);
|
File file = new File(directory, name);
|
||||||
file.setLastModified(System.currentTimeMillis());
|
file.setLastModified(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the length in bytes of a file in the directory. */
|
/** Returns the length in bytes of a file in the directory. */
|
||||||
public long fileLength(String name) {
|
public long fileLength(String name) {
|
||||||
|
ensureOpen();
|
||||||
File file = new File(directory, name);
|
File file = new File(directory, name);
|
||||||
return file.length();
|
return file.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes an existing file in the directory. */
|
/** Removes an existing file in the directory. */
|
||||||
public void deleteFile(String name) throws IOException {
|
public void deleteFile(String name) throws IOException {
|
||||||
|
ensureOpen();
|
||||||
File file = new File(directory, name);
|
File file = new File(directory, name);
|
||||||
if (!file.delete())
|
if (!file.delete())
|
||||||
throw new IOException("Cannot delete " + file);
|
throw new IOException("Cannot delete " + file);
|
||||||
|
@ -363,6 +369,7 @@ public class FSDirectory extends Directory {
|
||||||
*/
|
*/
|
||||||
public synchronized void renameFile(String from, String to)
|
public synchronized void renameFile(String from, String to)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
ensureOpen();
|
||||||
File old = new File(directory, from);
|
File old = new File(directory, from);
|
||||||
File nu = new File(directory, to);
|
File nu = new File(directory, to);
|
||||||
|
|
||||||
|
@ -427,7 +434,7 @@ public class FSDirectory extends Directory {
|
||||||
/** Creates a new, empty file in the directory with the given name.
|
/** Creates a new, empty file in the directory with the given name.
|
||||||
Returns a stream writing this file. */
|
Returns a stream writing this file. */
|
||||||
public IndexOutput createOutput(String name) throws IOException {
|
public IndexOutput createOutput(String name) throws IOException {
|
||||||
|
ensureOpen();
|
||||||
File file = new File(directory, name);
|
File file = new File(directory, name);
|
||||||
if (file.exists() && !file.delete()) // delete existing, if any
|
if (file.exists() && !file.delete()) // delete existing, if any
|
||||||
throw new IOException("Cannot overwrite: " + file);
|
throw new IOException("Cannot overwrite: " + file);
|
||||||
|
@ -436,6 +443,7 @@ public class FSDirectory extends Directory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sync(String name) throws IOException {
|
public void sync(String name) throws IOException {
|
||||||
|
ensureOpen();
|
||||||
File fullFile = new File(directory, name);
|
File fullFile = new File(directory, name);
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
int retryCount = 0;
|
int retryCount = 0;
|
||||||
|
@ -470,11 +478,13 @@ public class FSDirectory extends Directory {
|
||||||
|
|
||||||
// Inherit javadoc
|
// Inherit javadoc
|
||||||
public IndexInput openInput(String name) throws IOException {
|
public IndexInput openInput(String name) throws IOException {
|
||||||
|
ensureOpen();
|
||||||
return openInput(name, BufferedIndexInput.BUFFER_SIZE);
|
return openInput(name, BufferedIndexInput.BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inherit javadoc
|
// Inherit javadoc
|
||||||
public IndexInput openInput(String name, int bufferSize) throws IOException {
|
public IndexInput openInput(String name, int bufferSize) throws IOException {
|
||||||
|
ensureOpen();
|
||||||
return new FSIndexInput(new File(directory, name), bufferSize);
|
return new FSIndexInput(new File(directory, name), bufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,6 +496,7 @@ public class FSDirectory extends Directory {
|
||||||
|
|
||||||
|
|
||||||
public String getLockID() {
|
public String getLockID() {
|
||||||
|
ensureOpen();
|
||||||
String dirName; // name to be hashed
|
String dirName; // name to be hashed
|
||||||
try {
|
try {
|
||||||
dirName = directory.getCanonicalPath();
|
dirName = directory.getCanonicalPath();
|
||||||
|
@ -510,7 +521,8 @@ public class FSDirectory extends Directory {
|
||||||
|
|
||||||
/** Closes the store to future operations. */
|
/** Closes the store to future operations. */
|
||||||
public synchronized void close() {
|
public synchronized void close() {
|
||||||
if (--refCount <= 0) {
|
if (isOpen && --refCount <= 0) {
|
||||||
|
isOpen = false;
|
||||||
synchronized (DIRECTORIES) {
|
synchronized (DIRECTORIES) {
|
||||||
DIRECTORIES.remove(directory);
|
DIRECTORIES.remove(directory);
|
||||||
}
|
}
|
||||||
|
@ -518,6 +530,7 @@ public class FSDirectory extends Directory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
|
ensureOpen();
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,15 +237,7 @@ public class RAMDirectory extends Directory implements Serializable {
|
||||||
|
|
||||||
/** Closes the store to future operations, releasing associated memory. */
|
/** Closes the store to future operations, releasing associated memory. */
|
||||||
public void close() {
|
public void close() {
|
||||||
|
isOpen = false;
|
||||||
fileMap = null;
|
fileMap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws AlreadyClosedException if this IndexReader is closed
|
|
||||||
*/
|
|
||||||
protected final void ensureOpen() throws AlreadyClosedException {
|
|
||||||
if (fileMap == null) {
|
|
||||||
throw new AlreadyClosedException("this RAMDirectory is closed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,9 @@ import junit.textui.TestRunner;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.SimpleAnalyzer;
|
import org.apache.lucene.analysis.SimpleAnalyzer;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
|
||||||
import org.apache.lucene.store.FSDirectory;
|
import org.apache.lucene.store.FSDirectory;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
import org.apache.lucene.search.Similarity;
|
|
||||||
import org.apache.lucene.demo.FileDocument;
|
import org.apache.lucene.demo.FileDocument;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
@ -115,7 +113,6 @@ public class TestDoc extends LuceneTestCase {
|
||||||
SegmentInfo si2 = indexDoc(writer, "test2.txt");
|
SegmentInfo si2 = indexDoc(writer, "test2.txt");
|
||||||
printSegment(out, si2);
|
printSegment(out, si2);
|
||||||
writer.close();
|
writer.close();
|
||||||
directory.close();
|
|
||||||
|
|
||||||
SegmentInfo siMerge = merge(si1, si2, "merge", false);
|
SegmentInfo siMerge = merge(si1, si2, "merge", false);
|
||||||
printSegment(out, siMerge);
|
printSegment(out, siMerge);
|
||||||
|
@ -126,6 +123,7 @@ public class TestDoc extends LuceneTestCase {
|
||||||
SegmentInfo siMerge3 = merge(siMerge, siMerge2, "merge3", false);
|
SegmentInfo siMerge3 = merge(siMerge, siMerge2, "merge3", false);
|
||||||
printSegment(out, siMerge3);
|
printSegment(out, siMerge3);
|
||||||
|
|
||||||
|
directory.close();
|
||||||
out.close();
|
out.close();
|
||||||
sw.close();
|
sw.close();
|
||||||
String multiFileOutput = sw.getBuffer().toString();
|
String multiFileOutput = sw.getBuffer().toString();
|
||||||
|
@ -143,7 +141,6 @@ public class TestDoc extends LuceneTestCase {
|
||||||
si2 = indexDoc(writer, "test2.txt");
|
si2 = indexDoc(writer, "test2.txt");
|
||||||
printSegment(out, si2);
|
printSegment(out, si2);
|
||||||
writer.close();
|
writer.close();
|
||||||
directory.close();
|
|
||||||
|
|
||||||
siMerge = merge(si1, si2, "merge", true);
|
siMerge = merge(si1, si2, "merge", true);
|
||||||
printSegment(out, siMerge);
|
printSegment(out, siMerge);
|
||||||
|
@ -154,6 +151,7 @@ public class TestDoc extends LuceneTestCase {
|
||||||
siMerge3 = merge(siMerge, siMerge2, "merge3", true);
|
siMerge3 = merge(siMerge, siMerge2, "merge3", true);
|
||||||
printSegment(out, siMerge3);
|
printSegment(out, siMerge3);
|
||||||
|
|
||||||
|
directory.close();
|
||||||
out.close();
|
out.close();
|
||||||
sw.close();
|
sw.close();
|
||||||
String singleFileOutput = sw.getBuffer().toString();
|
String singleFileOutput = sw.getBuffer().toString();
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package org.apache.lucene.store;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
|
||||||
|
public class TestDirectory extends LuceneTestCase {
|
||||||
|
|
||||||
|
public void testDetectClose() throws Throwable {
|
||||||
|
Directory dir = new RAMDirectory();
|
||||||
|
dir.close();
|
||||||
|
try {
|
||||||
|
dir.createOutput("test");
|
||||||
|
fail("did not hit expected exception");
|
||||||
|
} catch (AlreadyClosedException ace) {
|
||||||
|
}
|
||||||
|
|
||||||
|
dir = FSDirectory.getDirectory(System.getProperty("tempDir"));
|
||||||
|
dir.close();
|
||||||
|
try {
|
||||||
|
dir.createOutput("test");
|
||||||
|
fail("did not hit expected exception");
|
||||||
|
} catch (AlreadyClosedException ace) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue