I’m using Javassist (3.25.0-GA) and Java 8 with a custom Agent to transform bytecode and add print statements to existing catch{} clauses. This works for simple cases, but has a problem with the compiled bytecode of the try-with-resources syntax.
Here is a basic example of what I'm trying to do and the results when it works correctly on standard try/catch blocks:
    // before byte code manipulation
    public void methodWithCatchClause() {
        try {
            throwsAnException();
        } catch (Exception ex) {
            handleException(ex);
        }
    }
    // after byte code manipulation
    public void methodWithCatchClause() {
        try {
            throwsAnException();
        } catch (Exception ex) {
            System.out.println("CATCH CLAUSE!"); // added by Javassist
            handleException(ex);
        }
    }
The logic I'm using to transform the bytecode is inspired by another SO post [0]:
    // from https://stackoverflow.com/questions/51738034/javassist-insert-a-method-at-the-beginning-of-catch-block
    ControlFlow cf = new ControlFlow(ctMethod); // ctMethod == methodWithCatchClause()
    for (ControlFlow.Block block : cf.basicBlocks()) {
        ControlFlow.Catcher catchers[] = block.catchers();
        for (int i = 0; i < catchers.length; i++) {
            ControlFlow.Catcher catcher = catchers[i];
            ControlFlow.Block catcherBlock = catcher.block();
            int position = catcherBlock.position();
            int lineNumber = ctMethod.getMethodInfo().getLineNumber(position);
            ctMethod.insertAt(lineNumber + 1, "System.out.println(\"CATCH CLAUSE!\");");
        }
    }
But this code breaks in conjunction with the try-with-resources syntax. As a concrete example this code:
    public void tryWithResources() {
        try (TestAutoClosable test = new TestAutoClosable()) {
            test.doStuff();
        } catch (Exception ex) {
            handleException(ex);
        }
    }
Turns into this after code generation:
   public void tryWithResources() {
        try {
            TestAutoClosable test = new TestAutoClosable();
            Throwable var2 = null;
            try {
                System.out.println("CATCH CLAUSE!");
                test.doStuff();
            } catch (Throwable var12) {
                var2 = var12;
                throw var12;
            } finally {
                if (test != null) {
                    if (var2 != null) {
                        try {
                            test.close();
                        } catch (Throwable var11) {
                            var2.addSuppressed(var11);
                        }
                    } else {
                        test.close();
                    }
                }
            }
        } catch (Exception var14) {
            System.out.println("CATCH CLAUSE!");
            System.out.println("CATCH CLAUSE!");
            System.out.println("CATCH CLAUSE!");
            // this goes on for 15 more entries...
            this.handleException(var14);
        }
    }
This of course is causing "CATCH CLAUSE!" to be printed multiple times in odd places. It might be helpful to mention that empty catch clauses, regardless of try/catch syntax, break in a similar fashion (maybe the underlying cause is related?).
I would expect something closer to this as the end result:
    public void tryWithResources() {
        try {
            TestAutoClosable test = new TestAutoClosable();
            Throwable var2 = null;
            try {
                test.noop();
            } catch (Throwable var12) {
                System.out.println("CATCH CLAUSE!");
                var2 = var12;
                throw var12;
            } finally {
                if (test != null) {
                    if (var2 != null) {
                        try {
                            test.close();
                        } catch (Throwable var11) {
                            var2.addSuppressed(var11);
                        }
                    } else {
                        test.close();
                    }
                }
            }
        } catch (Exception var14) {
            this.handleException(var14);
        }
    }
I'm trying to figure out if I have a simple error in my code or if my approach is entirely wrong. I would appreciate any help with the matter. Thanks in advance.
[0] Javassist: insert a method at the beginning of catch block
