diff --git a/CHANGES.txt b/CHANGES.txt index ff7b56844c9..d93bb84567b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -717,6 +717,9 @@ Release 0.22.0 - Unreleased HADOOP-7305. Eclipse project classpath should include tools.jar from JDK. (Niels Basjes via todd) + HADOOP-7318. MD5Hash factory should reset the digester it returns. + (todd via eli) + Release 0.21.1 - Unreleased IMPROVEMENTS diff --git a/src/java/org/apache/hadoop/io/MD5Hash.java b/src/java/org/apache/hadoop/io/MD5Hash.java index f19f8db12c9..54be96bfa2a 100644 --- a/src/java/org/apache/hadoop/io/MD5Hash.java +++ b/src/java/org/apache/hadoop/io/MD5Hash.java @@ -98,7 +98,9 @@ public class MD5Hash implements WritableComparable { * Create a thread local MD5 digester */ public static MessageDigest getDigester() { - return DIGESTER_FACTORY.get(); + MessageDigest digester = DIGESTER_FACTORY.get(); + digester.reset(); + return digester; } /** Construct a hash value for the content from the InputStream. */ diff --git a/src/test/core/org/apache/hadoop/io/TestMD5Hash.java b/src/test/core/org/apache/hadoop/io/TestMD5Hash.java index feb1107ed46..86fefcf561c 100644 --- a/src/test/core/org/apache/hadoop/io/TestMD5Hash.java +++ b/src/test/core/org/apache/hadoop/io/TestMD5Hash.java @@ -20,6 +20,9 @@ package org.apache.hadoop.io; import org.apache.hadoop.io.TestWritable; import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.security.MessageDigest; import java.util.Random; @@ -109,7 +112,38 @@ public class TestMD5Hash extends TestCase { t2.start(); t1.join(); t2.join(); - } - + + public void testFactoryReturnsClearedHashes() throws IOException { + // A stream that will throw an IOE after reading some bytes + ByteArrayInputStream failingStream = new ByteArrayInputStream( + "xxxx".getBytes()) { + @Override + public synchronized int read(byte[] b) throws IOException { + int ret = super.read(b); + if (ret <= 0) { + throw new IOException("Injected fault"); + } + return ret; + } + }; + final String TEST_STRING = "hello"; + + // Calculate the correct digest for the test string + MD5Hash expectedHash = MD5Hash.digest(TEST_STRING); + + // Hashing again should give the same result + assertEquals(expectedHash, MD5Hash.digest(TEST_STRING)); + + // Try to hash a stream which will fail halfway through + try { + MD5Hash.digest(failingStream); + fail("didnt throw!"); + } catch (Exception e) { + // expected + } + + // Make sure we get the same result + assertEquals(expectedHash, MD5Hash.digest(TEST_STRING)); + } }