アプリケーションにシャットダウンフックがあります(Runtime.getRuntime().addShutdownHook
を使用して作成)。ただし、Eclipse内からアプリケーションを起動すると、シャットダウン時にシャットダウンフックが実行されません。
これは、Eclipseが強制終了シグナルに相当するものをプロセスに送信し、シャットダウンフックが実行されないためだと思います(Windowsのtaskkill/FまたはLinuxのkill -pに相当)絶対にわからない。
誰もこれを回避する方法を知っていますか? Windows(Vista)を実行していますが、Windows固有の問題であると感じていますが、よくわかりません。
メインメソッドの最後に次のハックを使用して、問題を回避しました。
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を使用しているため、確認できません。申し訳ありません。ただし、次のテストプログラムdoesが期待どおりシャットダウンフックを実行することを伝えることができます。
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." );
}
}
Runtime#addShutdownHook のJavadocには、JVMが異常終了した場合、正常に終了しない場合にシャットダウンフックが実行されないことが記載されています。そうは言っても、試してみるべきことがいくつかあります。繰り返しますが、申し訳ありませんが、これらを事前に確認することはできません。ここにはWindowsはありません。 (祝福!)
以下は、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'"
Windowsでは、送信する必要のある標準的な方法でJavaアプリケーションを正常に停止するには Ctrl + C それに。これはコンソールアプリでのみ機能しますが、Eclipseはjavaw.exe
の代わりに Java.exe
。これを解決するには、起動構成の[JRE]タブを開き、[代替JRE:]を選択します。 「Java実行可能ファイル」グループボックスが表示され、代替実行可能ファイル「Java」を入力できます。
ここで、Ctrl-Cを非表示のコンソールを持つプロセスに送信する外部プログラムが必要です。ヒントを見つけました here および here 。プログラムは、目的のプロセスのコンソールに接続し、コンソールイベントを送信します。
#include <stdio.h>
#include <windows.h>
int main(int argc, char* argv[])
{
if (argc == 2) {
unsigned pid = 0;
if (sscanf_s(argv[1], "%u", &pid) == 1) {
FreeConsole(); // AttachConsole will fail if we don't detach from current console
if (AttachConsole(pid)) {
//Disable Ctrl-C handling for our program
SetConsoleCtrlHandler(NULL, TRUE);
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
return 0;
}
}
}
return 1;
}
テストJavaプログラム:
public class Shuthook {
public static void main(final String[] args) throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("Shutting down...");
}
});
String sPid = ManagementFactory.getRuntimeMXBean().getName();
sPid = sPid.substring(0, sPid.indexOf('@'));
System.out.println("pid: " + sPid);
System.out.println("Sleeping...");
Thread.sleep(1000000);
}
}
終了する:
C:\>killsoft.exe 10520
Eclipseでのプログラム出力のテスト:
pid: 10520
Sleeping...
Shutting down...
私はこれを修正する方法がわかりませんが、IntelliJは「実行」ダイアログに別のボタンを追加し、シャットダウンフックを呼び出す方法でVMをシャットダウンします。特徴。
Sairamはここにあります。System.exit(0)を呼び出すことで、Eclipse JVMを終了し、シャットダウンフックの結果を確認できます。
私は現在、websphereで立ち往生しています。探しているものが見当たりません。ただし、Eclipseには、同じVMでのアプリケーションの起動に関連する実行構成オプションがあります。 JavaアプリケーションをEclipse VMと同じVMで起動することは可能ですか?
しかし、オプションは私の心を滑らせます。