HADOOP-7256. Resource leak during failure scenario of closing of resources. Contributed by Ramkrishna S. Vasudevan. (harsh)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1388893 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
bd76d9a827
commit
28023b7759
|
@ -215,6 +215,9 @@ Trunk (Unreleased)
|
||||||
HADOOP-8821. Fix findbugs warning related to concatenating string in a
|
HADOOP-8821. Fix findbugs warning related to concatenating string in a
|
||||||
for loop in Configuration#dumpDeprecatedKeys(). (suresh)
|
for loop in Configuration#dumpDeprecatedKeys(). (suresh)
|
||||||
|
|
||||||
|
HADOOP-7256. Resource leak during failure scenario of closing
|
||||||
|
of resources. (Ramkrishna S. Vasudevan via harsh)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
HADOOP-7761. Improve the performance of raw comparisons. (todd)
|
HADOOP-7761. Improve the performance of raw comparisons. (todd)
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.nio.channels.FileChannel;
|
||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.classification.InterfaceStability;
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
|
@ -36,6 +37,7 @@ import org.apache.hadoop.conf.Configuration;
|
||||||
@InterfaceAudience.Public
|
@InterfaceAudience.Public
|
||||||
@InterfaceStability.Evolving
|
@InterfaceStability.Evolving
|
||||||
public class IOUtils {
|
public class IOUtils {
|
||||||
|
public static final Log LOG = LogFactory.getLog(IOUtils.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies from one stream to another.
|
* Copies from one stream to another.
|
||||||
|
@ -235,7 +237,7 @@ public class IOUtils {
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
try {
|
try {
|
||||||
c.close();
|
c.close();
|
||||||
} catch(IOException e) {
|
} catch(Throwable e) {
|
||||||
if (log != null && log.isDebugEnabled()) {
|
if (log != null && log.isDebugEnabled()) {
|
||||||
log.debug("Exception in closing " + c, e);
|
log.debug("Exception in closing " + c, e);
|
||||||
}
|
}
|
||||||
|
@ -264,6 +266,7 @@ public class IOUtils {
|
||||||
try {
|
try {
|
||||||
sock.close();
|
sock.close();
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
|
LOG.debug("Ignoring exception while closing socket", ignored);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,36 @@ public class TestIOUtils {
|
||||||
Mockito.verify(outputStream, Mockito.atLeastOnce()).close();
|
Mockito.verify(outputStream, Mockito.atLeastOnce()).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopyBytesShouldCloseInputSteamWhenOutputStreamCloseThrowsRunTimeException()
|
||||||
|
throws Exception {
|
||||||
|
InputStream inputStream = Mockito.mock(InputStream.class);
|
||||||
|
OutputStream outputStream = Mockito.mock(OutputStream.class);
|
||||||
|
Mockito.doReturn(-1).when(inputStream).read(new byte[1]);
|
||||||
|
Mockito.doThrow(new RuntimeException()).when(outputStream).close();
|
||||||
|
try {
|
||||||
|
IOUtils.copyBytes(inputStream, outputStream, 1, true);
|
||||||
|
fail("Didn't throw exception");
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
}
|
||||||
|
Mockito.verify(outputStream, Mockito.atLeastOnce()).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopyBytesShouldCloseInputSteamWhenInputStreamCloseThrowsRunTimeException()
|
||||||
|
throws Exception {
|
||||||
|
InputStream inputStream = Mockito.mock(InputStream.class);
|
||||||
|
OutputStream outputStream = Mockito.mock(OutputStream.class);
|
||||||
|
Mockito.doReturn(-1).when(inputStream).read(new byte[1]);
|
||||||
|
Mockito.doThrow(new RuntimeException()).when(inputStream).close();
|
||||||
|
try {
|
||||||
|
IOUtils.copyBytes(inputStream, outputStream, 1, true);
|
||||||
|
fail("Didn't throw exception");
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
}
|
||||||
|
Mockito.verify(inputStream, Mockito.atLeastOnce()).close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCopyBytesShouldNotCloseStreamsWhenCloseIsFalse()
|
public void testCopyBytesShouldNotCloseStreamsWhenCloseIsFalse()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
@ -76,7 +106,7 @@ public class TestIOUtils {
|
||||||
Mockito.verify(inputStream, Mockito.atMost(0)).close();
|
Mockito.verify(inputStream, Mockito.atMost(0)).close();
|
||||||
Mockito.verify(outputStream, Mockito.atMost(0)).close();
|
Mockito.verify(outputStream, Mockito.atMost(0)).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCopyBytesWithCountShouldCloseStreamsWhenCloseIsTrue()
|
public void testCopyBytesWithCountShouldCloseStreamsWhenCloseIsTrue()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
@ -117,7 +147,7 @@ public class TestIOUtils {
|
||||||
Mockito.verify(inputStream, Mockito.atLeastOnce()).close();
|
Mockito.verify(inputStream, Mockito.atLeastOnce()).close();
|
||||||
Mockito.verify(outputStream, Mockito.atLeastOnce()).close();
|
Mockito.verify(outputStream, Mockito.atLeastOnce()).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWriteFully() throws IOException {
|
public void testWriteFully() throws IOException {
|
||||||
final int INPUT_BUFFER_LEN = 10000;
|
final int INPUT_BUFFER_LEN = 10000;
|
||||||
|
@ -148,6 +178,7 @@ public class TestIOUtils {
|
||||||
for (int i = HALFWAY; i < input.length; i++) {
|
for (int i = HALFWAY; i < input.length; i++) {
|
||||||
assertEquals(input[i - HALFWAY], output[i]);
|
assertEquals(input[i - HALFWAY], output[i]);
|
||||||
}
|
}
|
||||||
|
raf.close();
|
||||||
} finally {
|
} finally {
|
||||||
File f = new File(TEST_FILE_NAME);
|
File f = new File(TEST_FILE_NAME);
|
||||||
if (f.exists()) {
|
if (f.exists()) {
|
||||||
|
@ -177,7 +208,7 @@ public class TestIOUtils {
|
||||||
"Error while reading compressed data", ioe);
|
"Error while reading compressed data", ioe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipFully() throws IOException {
|
public void testSkipFully() throws IOException {
|
||||||
byte inArray[] = new byte[] {0, 1, 2, 3, 4};
|
byte inArray[] = new byte[] {0, 1, 2, 3, 4};
|
||||||
|
|
Loading…
Reference in New Issue