Java 如何调用在另一个线程中运行的程序的关闭挂钩

Java 如何调用在另一个线程中运行的程序的关闭挂钩,java,multithreading,shutdown-hook,systemexit,Java,Multithreading,Shutdown Hook,Systemexit,我正在使用Jemmy框架为Swing应用程序编写自动化测试 我的测试套件通过在新线程中调用其主类的main方法来运行此应用程序 我已经编写了很多与GUI相关的测试,但现在我有了一个更复杂的任务 我需要检查被测试的应用程序在关闭时是否对文件夹进行了清理。此操作可能作为关闭挂钩执行。是否可以在不调用System.exit(0)的情况下调用该应用程序的关闭挂钩 调用此命令时,两个线程都将终止。但我希望在关闭测试应用程序后,带有测试的线程继续运行,以便检查这些文件夹是否仍然存在。在不改变我的测试套件的体

我正在使用Jemmy框架为Swing应用程序编写自动化测试

我的测试套件通过在新线程中调用其主类的main方法来运行此应用程序

我已经编写了很多与GUI相关的测试,但现在我有了一个更复杂的任务

我需要检查被测试的应用程序在关闭时是否对文件夹进行了清理。此操作可能作为关闭挂钩执行。是否可以在不调用System.exit(0)的情况下调用该应用程序的关闭挂钩


调用此命令时,两个线程都将终止。但我希望在关闭测试应用程序后,带有测试的线程继续运行,以便检查这些文件夹是否仍然存在。在不改变我的测试套件的体系结构的情况下调用关闭挂钩是否可能?

我发现了这个问题,但我没有测试它:

ApplicationShutdownHooks.hook().run(); // JRE 6
ApplicationShutdownHooks.runHooks();   // JRE 7
如您所见,方法的名称随着时间的推移而改变,这意味着您确实不应该这样做。然而,我认为这应该做的工作,但类是私人的。使用一些反射,您可以强制执行它

// 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);
}

将关闭钩子的重要部分放在不同的方法/类中,然后就可以对代码进行单元测试,而不必运行整个应用程序。然后,假设您在应用程序启动时注册了钩子,那么您应该能够非常依赖JVM来调用钩子,因此不测试钩子实际执行的事实在我看来并不可怕。如果您确实需要测试完整的端到端行为,无论如何,您可能应该在与应用程序uder测试分离的进程中运行测试代码,在这种情况下,您可以测试实际的预期清理行为,而无需“插入”挂钩(例如,检查某些文件在应用程序启动后确实存在,但在应用程序关闭后消失).

如果要编写测试,最好编写好的测试

您不需要干扰JVM来结束一个线程,但不需要结束另一个线程:您只需要确保在关闭窗口时执行关闭代码,否则将假定非正常关闭。将代码放在一个可以单独测试的方法中,就完成了。很可能您真的不需要向JVM添加关闭挂钩


您可能需要检查(并可能修复)引导代码中的系统状态。

这里的问题是,我不是该应用程序的开发人员,因此无法影响其实现方式。我只获取jar文件并测试其行为。我使用自己的安全管理器来防止应用程序终止我的测试套件,因此当单击“退出”按钮时,什么也不会发生。@那么,为什么不将测试安排为在单独的JVM中启动外部jar(我指的是另一个进程)而不是你用来启动测试的那个?我不能在另一个进程中运行它。Jemmy测试必须在与被测试应用程序相同的JVM中执行,因为它们在内存中搜索Swing组件。