Whence System.exit()?

A few days ago I was asked how to determine where in a Java program the call System.exit() is made. I came up with the following:

import java.util.Map;

public class TestSystemExit {
    public void methodOne() {
        methodTwo();
    }

    public void methodTwo() {
        methodThree();
    }

    public void methodThree() {
        methodFour();
    }
    
    public void methodFour() {
        System.exit(0);
    }

    public static void printStackTrace(Thread thread, StackTraceElement[] stElmts) {
        System.err.println("thread: " + thread);
        for (StackTraceElement stElmt : stElmts) {
            System.err.println("\tat " + stElmt);
        }
    }

    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                Map stMap = Thread.getAllStackTraces();
                
                // only dump the stack trace with the method "exit":                
                for (Map.Entry stElmt : stMap.entrySet()) {
                    for (StackTraceElement st : stElmt.getValue()) {
                        if ((st.getClassName() + "." + st.getMethodName()).equals("java.lang.System.exit")) {
                            printStackTrace(stElmt.getKey(), stElmt.getValue());
                            break;
                        }
                    }
                }
            }
        });
        
        TestSystemExit tse = new TestSystemExit();
        tse.methodOne();
    }
}

The output is as follows:

thread: Thread[main,5,main]
	at java.lang.Object.wait(Native Method)
	at java.lang.Thread.join(Thread.java:1203)
	at java.lang.Thread.join(Thread.java:1256)
	at java.lang.ApplicationShutdownHooks.run(ApplicationShutdownHooks.java:97)
	at java.lang.Shutdown.runHooks(Shutdown.java:106)
	at java.lang.Shutdown.sequence(Shutdown.java:150)
	at java.lang.Shutdown.exit(Shutdown.java:195)
	at java.lang.Runtime.exit(Runtime.java:107)
	at java.lang.System.exit(System.java:923)
	at TestSystemExit.methodFour(TestSystemExit.java:17)
	at TestSystemExit.methodThree(TestSystemExit.java:13)
	at TestSystemExit.methodTwo(TestSystemExit.java:9)
	at TestSystemExit.methodOne(TestSystemExit.java:5)
	at TestSystemExit.main(TestSystemExit.java:46)

DoctorJ 5.2.0 and DiffJ 1.2.0 Released

DoctorJ 5.2.0 is an extensive rewrite of the code, with unit tests expanded and refined. It uses the latest version of PMD as the parsing and AST code, and is the first version of DoctorJ to use the IJDK module, leading to much more elegant code. In terms of functionality this version add spell-checking for strings of a minimal length (which defaults to 2). The project now builds with Gradle.

DiffJ 1.2.0 also has significantly rewritten code, and also uses the IJDK module. This version adds (on terminals that support it) colorization of differences. It too uses Gradle for its build.

Both projects are now distributed only in zip format, and I welcome offers to repackage them for various package managers.

The distributes are available for download: