2009-11-17 8 views
6

Jaki jest najlepszy sposób, aby program (Java) rozpoznał, że po ostatnim uruchomieniu uległ awarii i wyświetli komunikat o następującej treści: "Wygląda na to, że ten program uległ awarii po raz ostatni." Zgłoś ten problem tutaj: bla @ foo. com .... "Czy program rozpoznaje awarię po raz ostatni?

Czy jest zalecany sposób robienia tego? (Złe?) Pomysły, które miałem:

  • Poproś program o zapisanie tymczasowego pliku klucza podczas uruchamiania, a następnie usuń go przy regularnym zamykaniu. Jeśli plik istnieje podczas uruchamiania, pokaż komunikat.
  • Rozpoznawanie zakleszczeń i przechowywanie "pliku błędów" w tym przypadku. Jeśli podczas uruchamiania pojawi się "plik błędów", wyświetl komunikat o błędzie i przenieś plik do archiwum lub coś podobnego.

Odpowiedz

7

są trzy powody, dla których program Java może awarii:

  • Unhandled RuntimeException. Jest to łatwe do rozwiązania z try-catch w main.
  • Nieobsługiwane błędy. Są one rzadkie, ale można je również złapać w main. Zwykle łapię Throwable w main. Zobacz poniżej szablon.
  • Jeśli używasz wątków, spójrz na Thread.setDefaultUncaughtExceptionHandler().
  • Błędy w maszynie wirtualnej lub program zabity przez użytkownika lub gwałtowne zamknięcie sprzętu. Doprowadzą one do awarii, której nie można złapać. Tutaj najlepszą opcją jest utworzenie pliku flag gdzieś z new File(...).deleteOnExit(). Java oczyści to dla ciebie, jeśli będzie miała szansę.

Problem z zakleszczeniami polega na wykrywaniu zakleszczenia. Nie widziałem jeszcze spójnego sposobu, by to zrobić.

import org.apache.commons.lang.exception.ExceptionUtils; 

public class Demo 
{ 
    public static void main (String[] args) 
    { 
     try 
     { 
      Demo obj = new Demo(); 
      obj.run (args); 
      System.out.println ("Done."); 
     } 
     catch (Throwable t) 
     { 
      ExceptionUtils.printRootCauseStackTrace (t); 
     } 
    } 
} 
+0

lub program zabity przez użytkownika lub gwałtowne wyłączenie sprzętu itp. – kriss

+1

To powoduje tylko problemy z "głównym" wątkiem. Jeśli uruchomisz dodatkowe wątki, jeśli zgłoszą wyjątek czasu wykonywania lub błąd, wiadomość zostanie utracona. –

+0

@mlk: dziękuję, zaktualizowałem odpowiedź. –

3

Crash jak w nieprzechodanym wyjątku? Użyj numeru Thread.setDefaultUncaughtExceptionHandler i wyświetl komunikat jako część awarii.

Na pierwszy rzut oka, w jaki sposób obsługiwać wiele wystąpień aplikacji działających w tym samym czasie? (Pomyśl także o środowiskach wielu użytkowników).

Rozpoznawanie zakleszczeń - Jak często występują zakleszczenia? Sądzę, że możesz monitorować thread states we wszystkich "kluczowych" wątkach.

Masz zewnętrzne siły, które zabijają aplikację, jeśli zostaną uznane za problem, który powinieneś zgłosić? Po tym wszystkim, że twoja aplikacja nie zawiniła w tym przypadku.

Na koniec zawsze przechowuj "plik błędów" w formie dziennika. Użyj odpowiedniej struktury logowania (np. Java Logging lub Log4J). Możesz sprawdzić ostatnie wiersze tego dla sygnału, że aplikacja zakończyła się normalnie, ale znowu musisz zachować ostrożność w środowiskach z wieloma instancjami.

0

Co mogę zrobić, to przekierowanie System.err do pliku, tak, że kończy się w pliku mogę później przetwarzać komunikat błędu (jak awarie) ...

kodu do tego jest dość proste. ..

String errLog = "c:\\myLog"; 
try 
{ 
    java.io.PrintStream err = new java.io.PrintStream(new java.io.FileOutputStream(errLog)); 
    System.setErr(err); 
} 
catch (java.io.FileNotFoundException fnfe) {} 
+2

Zalecam użycie odpowiedniej struktury logowania przed przekierowaniem System.err. –

0

Zamierzam naśladować tutaj Marcosa. Utwórz plik konfiguracyjny lub log, który będzie zawierał ostatni komunikat o błędzie i datę ostatniego uruchomienia programu. Następnie przeczytaj ten plik podczas ładowania programu.

2

Wariant pierwszego proponowanego rozwiązania jest dość powszechny na Un * x dla procesów: przechowuj plik pid uruchomionego procesu w pliku podczas uruchamiania. Po ponownym uruchomieniu programu można sprawdzić, czy plik ten nadal istnieje (i nawet jeśli proces z tym pidem jest uruchomiony).

Z Javą prawdopodobnie mógłbyś zaadaptować ten pomysł za pomocą Threadid zdefiniowanego w ThreadMXBean. Ale zrobiłby to każdy plik. Plik zawierający klucz, który proponujesz, wydaje się być wystarczająco dobrym sposobem. Możesz również umieścić w nim przydatne informacje, takie jak czas ostatniego wykonania. Jeśli nadal jest na starcie, program nie został przerwany.

Może to również wyglądać jak plik dziennika uruchamiania, który śledzi zdarzenia programów, w tym uruchamianie i czyszczenie przystanków, a także blokad.

0

Wiele z tych odpowiedzi dotyczy wyjątków śledzenia, które spowodowały, że aplikacja przestała działać.

Inną możliwością jest zamknięcie aplikacji (np. Użytkownik ją zabił, wyłączenie komputera, przerwa w zasilaniu itp.). Myślę, że twój tymczasowy kluczowy pomysł będzie na to działać. Jest podobny do tego, w jaki sposób programy do edycji tekstu, takie jak vi lub Word, automatycznie tworzą specjalną kopię edytowanego pliku. Po otwarciu sprawdza, czy istnieje specjalna kopia i pyta, czy chcesz odzyskać plik.

Powiązane problemy