Merge branch 'use-try-with-resources' into 'master'

Use try-with-resources ('code smell' found with SonarQube).

See merge request asm/asm!253
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java
index 662abf6..016bf90 100644
--- a/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java
@@ -341,13 +341,10 @@
    */
   // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
   protected long computeSVUID() throws IOException {
-    ByteArrayOutputStream byteArrayOutputStream = null;
-    DataOutputStream dataOutputStream = null;
     long svuid = 0;
 
-    try {
-      byteArrayOutputStream = new ByteArrayOutputStream();
-      dataOutputStream = new DataOutputStream(byteArrayOutputStream);
+    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream)) {
 
       // 1. The class name written using UTF encoding.
       dataOutputStream.writeUTF(name.replace('/', '.'));
@@ -414,10 +411,6 @@
       for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
         svuid = (svuid << 8) | (hashBytes[i] & 0xFF);
       }
-    } finally {
-      if (dataOutputStream != null) {
-        dataOutputStream.close();
-      }
     }
 
     return svuid;
diff --git a/asm/src/main/java/org/objectweb/asm/ClassReader.java b/asm/src/main/java/org/objectweb/asm/ClassReader.java
index b73118f..ecf39a7 100644
--- a/asm/src/main/java/org/objectweb/asm/ClassReader.java
+++ b/asm/src/main/java/org/objectweb/asm/ClassReader.java
@@ -299,8 +299,7 @@
     if (inputStream == null) {
       throw new IOException("Class not found");
     }
-    try {
-      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
       byte[] data = new byte[INPUT_STREAM_DATA_CHUNK_SIZE];
       int bytesRead;
       while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java
index 4f0cc04..148fec0 100644
--- a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java
@@ -144,8 +144,7 @@
   }
 
   private static byte[] readInputStream(final InputStream inputStream) throws IOException {
-    try {
-      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
       byte[] data = new byte[8192];
       int bytesRead;
       while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
@@ -153,8 +152,6 @@
       }
       outputStream.flush();
       return outputStream.toByteArray();
-    } finally {
-      inputStream.close();
     }
   }
 
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JClassLibGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JClassLibGenerator.java
index 57fdd3e..fc2b0a7 100644
--- a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JClassLibGenerator.java
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JClassLibGenerator.java
@@ -131,11 +131,11 @@
       classFile.setMethods(new MethodInfo[] {methodInfo1, methodInfo2});
       classFile.setAttributes(new AttributeInfo[] {sourceFileAttribute});
 
-      ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-      DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
-      classFile.write(dataOutputStream);
-      dataOutputStream.close();
-      return byteArrayOutputStream.toByteArray();
+      try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+          DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream)) {
+        classFile.write(dataOutputStream);
+        return byteArrayOutputStream.toByteArray();
+      }
     } catch (IOException | InvalidByteCodeException e) {
       throw new RuntimeException("Class generation failed", e);
     }
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JavassistAdapter.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JavassistAdapter.java
index d55fea5..89c6e2e 100644
--- a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JavassistAdapter.java
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JavassistAdapter.java
@@ -45,11 +45,11 @@
   public byte[] readAndWrite(final byte[] classFile, final boolean computeMax) {
     try {
       CtClass ctClass = new ClassPool().makeClass(new ByteArrayInputStream(classFile));
-      ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-      DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
-      ctClass.getClassFile().write(dataOutputStream);
-      dataOutputStream.close();
-      return byteArrayOutputStream.toByteArray();
+      try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+          DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream)) {
+        ctClass.getClassFile().write(dataOutputStream);
+        return byteArrayOutputStream.toByteArray();
+      }
     } catch (IOException e) {
       throw new IllegalArgumentException(e);
     }
diff --git a/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java b/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java
index fb98aae..5e7f867 100644
--- a/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java
+++ b/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java
@@ -134,17 +134,15 @@
         if (dst != null && !dst.getParentFile().exists() && !dst.getParentFile().mkdirs()) {
           throw new IOException("Cannot create directory " + dst.getParentFile());
         }
-        OutputStream outputStream = Files.newOutputStream((dst == null ? src : dst).toPath());
-        try {
+        try (OutputStream outputStream =
+            Files.newOutputStream((dst == null ? src : dst).toPath())) {
           outputStream.write(classWriter.toByteArray());
-        } finally {
-          outputStream.close();
         }
       }
     }
   }
 
-  /** A ClassVisitor that retrofits classes from 1.6 to 1.5 version. */
+  /** A ClassVisitor that retrofits classes to 1.5 version. */
   static class ClassRetrofitter extends ClassVisitor {
 
     public ClassRetrofitter(final ClassVisitor classVisitor) {
@@ -161,6 +159,36 @@
         final String[] interfaces) {
       super.visit(Opcodes.V1_5, access, name, signature, superName, interfaces);
     }
+
+    @Override
+    public MethodVisitor visitMethod(
+        final int access,
+        final String name,
+        final String descriptor,
+        final String signature,
+        final String[] exceptions) {
+      return new MethodVisitor(
+          api, super.visitMethod(access, name, descriptor, signature, exceptions)) {
+
+        @Override
+        public void visitMethodInsn(
+            final int opcode,
+            final String owner,
+            final String name,
+            final String descriptor,
+            final boolean isInterface) {
+          // Remove the addSuppressed() method calls generated for try-with-resources statements.
+          // This method is not defined in JDK1.5.
+          if (owner.equals("java/lang/Throwable")
+              && name.equals("addSuppressed")
+              && descriptor.equals("(Ljava/lang/Throwable;)V")) {
+            visitInsn(Opcodes.POP2);
+          } else {
+            super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+          }
+        }
+      };
+    }
   }
 
   /**