Java Shutdown Hook 스레드 내에서 종료 상태를 결정하십시오
-
18-09-2019 - |
문제
종료 후크 런타임 중 프로세스의 종료 상태를 결정하고 싶습니다.
상태 코드 (0 또는 0이 아닌)를 기반으로하는 논리를 원합니다.
(예 : 0이 아닌 경우 0이 아닌 다른 방법으로 경고 이메일을 보내십시오)
이 정보를 어떻게 얻을 수 있는지 아십니까?
해결책
나는 그것을 무시하려고했다 SecurityManager
checkExit(int status)
방법 -이 경우 작동합니다 System.exit(status)
그러나 어디서나 명시 적으로 호출됩니다. 그러나 응용 프로그램이 "정상적으로"(활성 스레드 없음)를 종료 할 때 상태를 설정하지 않거나 오류가 VM을 죽일 때 상태를 설정하지 않습니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.Permission;
public class ExitChecker {
public ExitChecker() {
System.setSecurityManager(new ExitMonitorSecurityManager());
Runtime.getRuntime().addShutdownHook(new Thread(new MyShutdownHook()));
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line = "";
while (!line.equalsIgnoreCase("Q")) {
try {
System.out.println("Press a number to exit with that status.");
System.out.println("Press 'R' to generate a RuntimeException.");
System.out.println("Press 'O' to generate an OutOfMemoryError.");
System.out.println("Press 'Q' to exit normally.");
line = input.readLine().trim();
processInput(line);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
}
private void processInput(String line) {
if (line.equalsIgnoreCase("Q")) {
// continue, will exit loop and exit normally
} else if (line.equalsIgnoreCase("R")) {
throwRuntimeException();
} else if (line.equals("O")) {
throwError();
} else {
// try to parse to number
try {
int status = Integer.parseInt(line);
callExit(status);
} catch(NumberFormatException x) {
// not a number.. repeat question...
System.out.println("\nUnrecognized input...\n\n");
}
}
}
public void callExit(int status) {
System.exit(status);
}
public void throwError() {
throw new OutOfMemoryError("OutOfMemoryError");
}
public void throwRuntimeException() {
throw new RuntimeException("Runtime Exception");
}
public static void main(String[] args) {
new ExitChecker();
}
private static class ExitMonitorSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission perm) {
//System.out.println(perm.getName());
//System.out.println(perm.getActions());
}
@Override
public void checkPermission(Permission perm, Object context) {
//System.out.println(perm.getName());
//System.out.println(perm.getActions());
}
@Override
public void checkExit(int status) {
System.out.println("Setting exit value via security manager...");
MyShutdownHook.EXIT_STATUS = status;
}
}
private static class MyShutdownHook implements Runnable {
public static Integer EXIT_STATUS;
public void run() {
System.out.println("In MyShutdownHook - exit status is " + EXIT_STATUS);
}
}
}
다른 팁
다음은 전용 클래스가 System.exit
전화를 통해 전화하십시오 doExit(int)
. 이 클래스는 또한 출구 상태를 저장 한 다음 이후에 종료 후크 역할을합니다.
public class ShutDownHook implements Runnable {
private volatile Integer exitStatus;
// Centralise all System.exit code under control of this class.
public void doExit(int exitStatus) {
this.exitStatus = exitStatus;
System.exit(exitStatus); // Will invoke run.
}
public void run() {
// Verify that an exit status has been supplied.
// (Application could have called System.exit(int) directly.)
if (this.exitStatus != null) {
switch(exitStatus) {
case 0: // Process based on exit status.
// Yada yada ...
}
}
}
}
응용 프로그램 ITELLF에서 왜 이렇게합니까? 응용 프로그램이 일반 작업의 일부로 이메일을 보내지 않는 경우 이러한 종류의 기능을 통합하는 것은 좋은 생각이 아닙니다. IMHO.
JVM 프로세스에서 적절한 반환 값을 설정하고 쉘 스크립트 또는 전자 메일의 조건부 생성을 처리하는 것을 신뢰합니다.
Shutdownhooks는 짧은 시간 동안 만 실행해야하며 이메일을 보내면 꽤 오랫동안 소비 할 수 있습니다.
출구 상태를 저장해야합니다 main
글로벌로 (public static
) 변수.
제휴하지 않습니다 StackOverflow