How can I use Java MD5 MessageDigest without catching NoSuchAlgorithmException?
Asked Answered
O

2

12

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?

Oblivion answered 3/4, 2014 at 1:52 Comment(4)
Sorry, no. Checked exceptions are Java's ball and chain for the rest of the eternity.Parnell
+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.)Tidewater
@ruakh: You can use StandardCharsets.UTF_8 in Java 7 and newer. :)Oblivion
@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? :-)Tidewater
A
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.

Authorship answered 3/4, 2014 at 2:22 Comment(0)
G
4

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

Glottic answered 23/4, 2014 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.