我的应用程序中有一个关闭钩子(使用创建Runtime.getRuntime().addShutdownHook
).但是,如果我从Eclipse中启动应用程序,当它关闭时,关闭挂钩不会执行.
我认为这是因为Eclipse向进程发送了一个强制终止信号的等价物,这不会导致关闭挂钩执行(相当于Windows上的taskkill/F或Linux上的kill -p),尽管我我不是很确定.
有谁知道怎么解决这个问题?我正在运行Windows(Vista),我觉得它可能是Windows特定的问题,但我不确定.
我在主要方法结束时使用了以下hack来解决问题:
if (Boolean.parseBoolean(System.getenv("RUNNING_IN_ECLIPSE"))) { System.out.println("You're using Eclipse; click in this console and " + "press ENTER to call System.exit() and run the shutdown routine."); try { System.in.read(); } catch (IOException e) { e.printStackTrace(); } System.exit(0); }
首先,您的申请结束还是强行结束?如果你强行结束它(通过停止按钮),这个Eclipse错误报告会详细说明为什么这可能不起作用.
如果做不到这一点,你可能是正确的,这是特定于Windows的行为.我在Mac上,所以我无法确认,抱歉.但是,我可以告诉您,以下测试程序确实按预期执行了关闭挂钩.
public class MyShutdownHook { public static void main( String[] args ) { System.out.println( "Entering main." ); Runtime.getRuntime().addShutdownHook( new Thread( new Runnable() { public void run() { System.out.println( "Shutdown hook ran." ); } } ) ); System.out.println( "Exiting main." ); } }
运行时的Javadocs #addShutdownHook确实提到当JVM中止而不正常退出时,关闭挂钩不运行,所以再次,你的假设可能是正确的.话虽这么说,这里有一些事情要尝试.再次,抱歉,我无法提前确认这些 - 这里没有Windows.(幸好!)
确保JVM不包含-Xrs选项.这对关闭钩子有副作用.
尝试使用-server或-client选项启动JVM .根据我的经验,边缘案例行为可以通过选择VM模式来实现.(特别是关于线程 - 至少在Mac上.)
您是在分析器等下启动应用程序吗?加载任何本地库?
你得到一些致命的错误而错过了吗?例如,OutOfMemoryError等?
尝试从Eclipse中的应用程序的"运行配置"对话框中选中/取消选中" 在后台启动"选项.
最后但并非最不重要的:如果有机会,请手动调用System.exit().:)
这是一个可以在eclipse之外运行的脚本,列出在Eclipse下运行的可用进程,你可以杀掉它们.
#!/bin/bash set -o nounset # Treat unset variables as an error PROCESSES=$(ps axo pid,ppid,command) # Find eclipse launcher PID LAUNCHER_PID=$(echo "$PROCESSES" | grep "/usr/lib/eclipse/eclipse" |grep -v "launcher"|awk '{print $1}') echo "Launcher PID $LAUNCHER_PID" # Find eclipse PID ECLIPSE_PID=$(echo "$PROCESSES" | egrep "[[:digit:]]* $LAUNCHER_PID " | awk '{print $1}') echo "Eclipse PID $ECLIPSE_PID" # Find running eclipse sub-process PIDs SUB_PROCESS=$(echo "$PROCESSES" | egrep "[[:digit:]]* $ECLIPSE_PID " | awk '{print $1}') # List processes echo for PROCESS in $SUB_PROCESS; do DRIVER=$(ps --no-headers o pid,ppid,command $PROCESS | awk '{print $NF}') echo "$PROCESS $DRIVER" done echo "Kill a process using: 'kill -SIGTERM \$PID'"