11

In Java, if I want to compute an MD5 sum, I need to be aware of possible exceptions:

try {
   MessageDigest md = MessageDigest.getInstance("MD5");
   // Do stuff
} catch (NoSuchAlgorithmException e) {
   // Can't happen...
}

However, according to the JVM spec, MD5 must be supported, so the exception should never be thrown. Is there a different access pattern that allows me to write more elegant code?

Paul Samsotha
  • 188,774
  • 31
  • 430
  • 651
MikeD
  • 3,138
  • 1
  • 19
  • 36
  • 8
    Sorry, no. Checked exceptions are Java's ball and chain for the rest of the eternity. – Seva Alekseyev Apr 03 '14 at 01:55
  • +1. I've often wondered if there's a better way to deal with methods that throw UnsupportedEncodingException when all I want is the mandatorily-supported UTF-8. (My solution so far has been to use `Throwables.propagate`, which is not too bad, but still.) – ruakh Apr 03 '14 at 01:57
  • 1
    @ruakh: You can use StandardCharsets.UTF_8 in Java 7 and newer. :) – MikeD Apr 03 '14 at 01:57
  • 2
    @MikeD: Ooh, nice, thanks! So I guess that answers your question, too: the elegant access pattern is "wait a few JDK versions until they add a more-specific method that circumvents the problem, then call that". What are your latency requirements? :-) – ruakh Apr 03 '14 at 01:59

2 Answers2

4

You could forget the Java implementation and use Guava's: http://docs.guava-libraries.googlecode.com/git-history/v11.0/javadoc/com/google/common/hash/Hashing.html#md5() . In Java you can't totally ignore a Checked Exception. You either catch it, or decorate your method with "throws Exception", or get a Library that isn't so pedantic. To me, the Guava variant below reads gets the job done with the least amount of ceremony client surprise.

// Its my problem, yuk...
public byte[] md5TheHardWay( String s ) {
    try {
        MessageDigest md = MessageDigest.getInstance( "MD5" );
        // Do stuff
        byte[] result = md.digest( s.getBytes() );
        return result;
    } catch ( NoSuchAlgorithmException e ) {
        // Can't happen...
        e.printStackTrace();
    }
    return null;
}

// Its your problem, yuk...
public byte[] md5ItsYourProblemClient( String s ) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance( "MD5" );
    // Do stuff
    byte[] result = md.digest( s.getBytes() );
    return result;
}

// Its no problem...I like Guava.
public byte[] md5ThroughGuava( String s ) {
    HashFunction md = Hashing.md5();
    HashCode code = md.hashBytes( s.getBytes() );
    return code.asBytes();
}

Surfing through the Guava code it is interesting how they do this. For all intents and purposes, the Guava library writer went the "Its my problem, yuk..." path, caught the checked exception, and turned it into a RuntimeException. Clever and effective.

// an excerpt from the Guava sourcecode
private static MessageDigest getMessageDigest(String algorithmName) {
  try {
    return MessageDigest.getInstance(algorithmName);
  } catch (NoSuchAlgorithmException e) {
    throw new AssertionError(e);
  }
}

Have I mentioned I love Guava? I love Guava.

Bob Kuhar
  • 9,765
  • 9
  • 56
  • 101
2

Instead of MessageDigest you can use common.apache DigestUtils. This is easy to use and no need to take such long procedure to digest data like MessageDigest does.

DigestUtils.md5("String to digest");

Go through this Class and follow this documentation

Harshal Patil
  • 6,284
  • 8
  • 37
  • 55