Posted By

dwijnand on 05/26/12


Tagged

java checksums


Versions (?)

Throwable Identifier


 / Published in: Java
 

A useful utility class to identify Throwables by creating a checksum (using a message digest, such as MD5 or SHA1) of its stack trace

  1. /** Identifies throwables by creating a checksum (using a message digest, such as MD5 or SHA1) of its stack trace. */
  2. public final class ThrowableIdentifier {
  3. private static final Logger LOGGER = Logger.getLogger(ThrowableIdentifier.class.getName());
  4.  
  5. private ThrowableIdentifier() { /* Utility class */}
  6.  
  7. /**
  8.   * Returns the checksum of the specified throwable, using a specific message digest, which is reset at the end. The returned
  9.   * byte array can be converted into a string by using {@link Strings#toHexString(byte[])}.
  10.   */
  11. public static byte[] getChecksum(final Throwable throwable, final MessageDigest messageDigest) throws IOException {
  12. return getChecksum(newStackTraceBytesStream(throwable), messageDigest);
  13. }
  14.  
  15. /**
  16.   * Returns the checksum of the specified input stream, using a specific message digest, which is reset at the end. The
  17.   * returned byte array can be converted into a string by using {@link Strings#toHexString(byte[])}.
  18.   */
  19. public static byte[] getChecksum(final InputStream in, final MessageDigest messageDigest) throws IOException {
  20. try {
  21. final byte[] buffer = new byte[0x1000];
  22. for (int count = in.read(buffer); count != -1; count = in.read(buffer))
  23. messageDigest.update(buffer, 0, count);
  24. return messageDigest.digest();
  25. } finally {
  26. messageDigest.reset();
  27. if (in != null) {
  28. try {
  29. in.close();
  30. } catch (IOException e) {
  31. LOGGER.log(Level.WARNING, "IOException thrown while closing InputStream", e);
  32. }
  33. }
  34. }
  35. }
  36.  
  37. /** Returns the hexadecimal string form of the specified byte array. */
  38. public static String toHexString(final byte... bytes) {
  39. final StringBuilder builder = new StringBuilder(2 * bytes.length);
  40. for (final byte b : bytes)
  41. builder.append(padStart(Integer.toHexString(0xff & b), 2, '0'));
  42. return builder.toString();
  43. }
  44.  
  45. /** Returns the specified string, if necessary padded with the specified character until the desired length is reached. */
  46. public static String padStart(String s, final int length, final char c) {
  47. if (s.length() < length) {
  48. final StringBuilder sb = new StringBuilder(length);
  49. for (int i = s.length(); i < length; i++) {
  50. sb.append(c);
  51. }
  52. s = sb.append(s).toString();
  53. }
  54. return s;
  55. }
  56.  
  57. /** Returns an input stream of the specified throwable's stack trace. */
  58. public static InputStream newStackTraceBytesStream(final Throwable throwable) {
  59. return new ByteArrayInputStream(getStackTrace(throwable).getBytes(Charset.forName("UTF-8")));
  60. }
  61.  
  62. /** Returns the specified throwable's stack trace. */
  63. public static String getStackTrace(final Throwable throwable) {
  64. final StringWriter stringWriter = new StringWriter();
  65. final PrintWriter printWriter = new PrintWriter(stringWriter);
  66. try {
  67. throwable.printStackTrace(printWriter);
  68. } finally {
  69. printWriter.close();
  70. }
  71. return stringWriter.toString();
  72. }
  73. }

Report this snippet  

You need to login to post a comment.