简体   繁体   中英

How to invoke shutdown hooks of a program running in another thread

I am writing automated tests for a Swing application using Jemmy framework.

My test suite run this application by invoking the main method of its Main class in a new thread.

I have already written a lot of GUI-related tests but now I have got a more complex task.

I need to check if the tested application does some clean up of folders when it is being closed. This action is probably executed as a shutdown hook. Is it somehow possible to invoke shutdown hooks of that application without calling System.exit(0) ?

When this command is called both threads will be terminated. But I want the thread with my tests to continue running after the tested application is closed so I can check if those folders still exist or not. Is it somehow possible to invoke the shutdown hooks without changing the architecture of my test suite?

I found this, but I didn't test it:

ApplicationShutdownHooks.hook().run(); // JRE 6
ApplicationShutdownHooks.runHooks();   // JRE 7

As you can see, the names of the methods changed over time, which means you really shouldn't do this. However, I think this should do the job, but the class is private. Using some reflection, you could force the execution of it.

// JRE 7
try
{
    Class cl = Class.forName("java.lang.ApplicationShutdownHooks");
    Method m = cl.getDeclaredMethod("runHooks");
    m.setAccessible(true);
    m.invoke(null);
} catch (Exception e)
{
    e.printStackTrace(System.out);
}

Put the important parts of your shutdown hooks in separate methods/classes, and then you will be able to unit-test this code without having to run the whole app. Then, assuming you do register the hooks at app startup, you should pretty much be able to rely on the JVM to call your hooks, so not testing the fact that the hooks actually get executed is not so terrible IMO. If you really need to test the full end-to-end behavior, you should probably be running your testing code in a process separate from the application uder test, anyway, in which case you can test the actual expected cleanup behavior without needing to "plug into" the hooks (eg check that some files do exist after application startup but disappear after the app shuts down).

If you're going to write tests, it's better to write good ones.

You don't need to mess with the JVM to end a thread but not the other: you only need to be sure that when the window is closed the shutdown code is executed, otherwise a non-graceful shutdown is assumed. Put that code in a method that you can test separately, and you're done. Likely you don't really need to add a shutdown hook to the JVM.

You may want to check (and possibly repair) the system status in your bootstrap code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM