diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java index 504394a0d5e..14fbeef1794 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java @@ -93,6 +93,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.BlockLocation; import org.apache.hadoop.fs.BlockStorageLocation; @@ -893,6 +894,17 @@ public synchronized void close() throws IOException { } } + /** + * Close all open streams, abandoning all of the leases and files being + * created. + * @param abort whether streams should be gracefully closed + */ + public void closeOutputStreams(boolean abort) { + if (clientRunning) { + closeAllFilesBeingWritten(abort); + } + } + /** * Get the default block size for this cluster * @return the default block size in bytes diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java index dc303e5db80..59d04fe41ed 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java @@ -846,10 +846,10 @@ protected boolean primitiveMkdir(Path f, FsPermission absolutePermission) @Override public void close() throws IOException { try { - super.processDeleteOnExit(); - dfs.close(); - } finally { + dfs.closeOutputStreams(false); super.close(); + } finally { + dfs.close(); } } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java index eb8a0137f54..2518bca9cc3 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java @@ -24,7 +24,9 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; - +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; import java.io.File; import java.io.FileNotFoundException; @@ -70,6 +72,7 @@ import org.apache.hadoop.util.Time; import org.apache.log4j.Level; import org.junit.Test; +import org.mockito.InOrder; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -169,7 +172,31 @@ public void testDFSClose() throws Exception { if (cluster != null) {cluster.shutdown();} } } + + @Test + public void testDFSCloseOrdering() throws Exception { + DistributedFileSystem fs = new MyDistributedFileSystem(); + Path path = new Path("/a"); + fs.deleteOnExit(path); + fs.close(); + + InOrder inOrder = inOrder(fs.dfs); + inOrder.verify(fs.dfs).closeOutputStreams(eq(false)); + inOrder.verify(fs.dfs).delete(eq(path.toString()), eq(true)); + inOrder.verify(fs.dfs).close(); + } + private static class MyDistributedFileSystem extends DistributedFileSystem { + MyDistributedFileSystem() { + statistics = new FileSystem.Statistics("myhdfs"); // can't mock finals + dfs = mock(DFSClient.class); + } + @Override + public boolean exists(Path p) { + return true; // trick out deleteOnExit + } + } + @Test public void testDFSSeekExceptions() throws IOException { Configuration conf = getTestConfiguration();