문제

Java 응용 프로그램의 모든 예외를 가로 채는 가장 간단한 방법은 무엇입니까? AOP는 이런 종류의 기능을 제공해야합니까, 아니면 동적 프록시로 수행 할 수 있습니까? 아니면 다른 방법이 있습니까? 가장 간단한 솔루션은 실행 성능에 미치는 영향과 관련하여 좋은 솔루션입니까? 주제에 대한 기술 노하우를 이해하려고 노력하면서 경험이 풍부한 개발자의 가능한 솔루션을 듣고 싶습니다.

편집하다:

이미 좋은 조언에 감사하지만 현재 조언은 확인 된 예외에만 적용되지 않습니까? nullpointerexceptions와 같은 검사되지 않은 예외는 어떻게 잡히지 않을 수 있고, 응용 프로그램을 잡을 때의 응용 프로그램이 힙/스택을 덤프하여 충돌 시점에 응용 프로그램의 현재 컨텍스트를 제공하는 것은 어떻습니까?

도움이 되었습니까?

해결책

Nate와 Konamiman에서 ... 당신이 제안하는 것은 전혀 효과가 없으며 OP의 질문에 대답하지 않습니다.

OP가 시도/캐치 내부에서 새 스레드를 시작하면 어떻게됩니까?

예를 들어:

public static void main(String[] args) {
    try {
        final Thread t = new Thread( new Runnable() {
            public void run() {
                System.out.println( 3 / Math.min(0,4) );
            }
        } );
        t.start();
    catch(Throwable t) {
        ...
    }
}

그럼 당신은 예외를 포착하지 않습니다.

이를 수행하는 올바른 방법은 Thread.SetDefaultUncuggexceptionHandler를 사용하는 것입니다.

다른 팁

로깅, 오류보고를 위해 모든 예외를 가로 채고 싶은 목적은 무엇입니까?

Java 프로그램의 모든 단일 라인에서 모든 단일 예외를 가로 채는 것이 가능하지만 아마도 성능이 상당히 발생할 수 있습니다. 피할 수 없다면 아마도 다음과 같은 것을 사용하는 것이 가장 좋을 것입니다. 종자, 컴파일 타임 (예 : 클래스 파일에 "직조")에서 실행할 수 있으며, 따라서 동적 프록시보다 훨씬 빠릅니다.

그러나 그것은 내가 모든 비용을 피하려고 노력하는 것입니다! 일반적으로 나는 잡으려는 예외의 범위를 제한하는 것이 낫다고 말할 것입니다. 또한 당신은 조사하고 싶을 수도 있습니다 Thread.SetDefaultUncugexceptionHandler입니다, GUI 응용 프로그램에서 오류 대화 상자를 표시하는 데 유용합니다.

Phil의 답변과 마찬가지로 여기에 upphed 예외 핸들러를 사용하는 방법을 보여주는 샘플 코드가 있습니다. 이것은 점검되지 않은 예외와 검사되지 않은 예외 모두에 적용됩니다.

편집 : 질문의 업데이트 된 주석을 기반으로 스택 추적을 인쇄하도록 업데이트되었습니다.

import java.lang.Thread.UncaughtExceptionHandler;

public class Test {

    public static void main(String[] args) throws Exception {
        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {

            @Override
            public void uncaughtException(Thread t, Throwable e) {
                e.printStackTrace();
            }}

        );

        // throw new RuntimeException(); /* this works too */
        throw new Exception();
    }

}
public static void main(String[] args) {
    try {
        ...
    catch(Throwable t) {
        ...
    }
}

단순히 모든 예외를 포착하는 것보다 더 중요한 것은 예외를 포착하는 것입니다.

  1. 당신이 그것에 대해 무언가를 할 수 없다면 예외를 포착하지 마십시오. 당신이 그것에 대해 아무것도 할 수 없다면, 다음 단계로 거품을 내거나 잡아 당기고,보다 구체적인 예외로 다시 찍어서 다시 삭감하십시오.

  2. 항상 Nate의 답변과 같은 전역 예외 처리 블록이있어 어느 곳에서나 처리 할 수없는 오류를 포착하여 다소 우아하게 실패 할 수 있습니다.

단순히 예외를 잡으려면 시도/캐치 블록으로 충분합니다. 그들이 던져 지거나 예외의 로깅 또는 포장을하지 않으려면이 작업을 수행하려면 AOP가 필요할 것입니다. SAGONTJ는 꽤 잘 처리하지만 잠재적 인 성능 병목 현상을 조심합니다.

동적 프록시는 메소드가 프록시 된 경우에만 작동하므로 프록시 객체의 실행 내부에서 예외가 발생하고 잡히면 프록시가 예외를 가로 채는 방법은 없습니다.

고려해야 할 한 가지는 모든 예외를 포착하거나 예외 만 확인하는 경우입니다. 모든 예외를 포착하려면 SageJ 's around throwing 또는 after throwing 조언은 모든 방법에 대한 일부 처리를 직조 할 것입니다. 여기에는 모든 방법 호출에서 JoinPoint 객체 및 합성 방법의 생성이 포함됩니다. 프로세스가 빡빡한 루프에 있지 않으면 쓰레기 수집이 지붕을 통과 할 수없는 경우에는 일반적으로 문제가되지 않습니다.

모든 예외를 포착해야 할 필요성에 의문을 제기하는 모든 사람들에게 ...

A가 있습니다 많은 모든 예외를 포착 해야하는 유효한 이유 :

  • 누군가 문제에 대해 이야기하는 GUI 앱에 대화 상자를 표시한다고 언급했습니다.
  • 제 3 자 API에서 버그를 중심으로 작업해야합니다.
  • 일부 JVM 구현에서 버그를 중심으로 작업합니다
  • 자체 치유 소프트웨어.
  • 자동 온라인 예외보고.

Java 그 자체 EDT (이벤트 디스패치 스레드)의 모든 예외를 가로 채고 EDT가 죽을 때 새로운 EDT를 스폰합니다. "자체 치유"소프트웨어의 형태를 고려할 수 있습니다. EDT 죽음은 들어 본 적이없는 것이 아니며 응용 프로그램이 올바르게 실행되는 것을 막지 않습니다 (반대로). (그리고, 예, 스윙과 AWT는 꽤 많은 버그를 가지고 있습니다.

자존심이있는 소프트웨어는 실제로 예기치 않은 예외 (100% 버그를 배송하고 새로운 릴리스, 버그 고정 릴리스를 얻지 못하는 모든 소프트웨어입니까?)의 경우를 고려해야한다고 주장 할 수 있습니다. 예상치 못한 예외가 발생합니다.

'Smart'는 소프트웨어가 EDT 케이스와 같은 소프트웨어가 충돌하지 못하게하거나 사용자에게 경고, 보고서 보내기 등을 방지 할 수 있습니다.

답변은 그러한 일을해야 할 필요성에 의문을 제기하거나 그렇게하는 것이 나쁜 관행이라고 제안합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top