2012-01-04 11 views
6

Mam trzy klasy, powiedzmy, alfa, beta, gamma i każda z trzech klas ma metodę main.Jak uruchomić kod po wywołaniu Sytem.exit (0) w końcu bloku

alfa- i klas beta mają, w ich metody main, A try...catch...finally blok jak:

public class alpha{ 

    public static void main(String[] args){ 
     try{ 
      Do something; 
     }catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
     finally{ 
      System.exit(0); 
     } 
    } 
} 


public class beta{ 

    public static void main(String[] args){ 
     try{ 
      Do something; 
     }catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
     finally{ 
      System.exit(0); 
     } 
    } 
} 

Teraz w klasie gamma zgłoszę główne metody klas alfa i beta do pracy ciągłej, jak poniżej

public gamma{ 

    public static void main(String[] args) { 
     try { 
      alpha.main(arg); 
      beta.main(arg1); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
} 

Problem polega na tym, że kod beta.main(arg1) nigdy nie został osiągnięty z powodu bloku System.exit(0) wewnątrz bloku klasy alpha klasy finally. Ponieważ alfa i beta są samodzielnymi aplikacjami, gdy są wykonywane oddzielnie, powinny zakończyć usługę po zakończeniu programu. Więc teraz jest jakikolwiek sposób, aby dotrzeć do linii beta.main(arg1) bez znacznej zmiany rzeczywistej funkcjonalności klas alfa i beta.

Uprzejmie proszę o kontakt, jeśli potrzebujesz więcej informacji. góry dzięki ...

+1

możliwe duplikat [Zapobieganie System.exit() z API] (http://stackoverflow.com/questions/5401281/preventing-system -exit-from-api) – Mat

Odpowiedz

4

W takim przypadku, hak zamknięcie można stosować:

public class Gamma{ 

    public static void main(String[] args) { 
     try { 
     Thread hook = new Thread() { public void run() { Beta.main(args); } }; 
      hook.setDaemon(true); 
      Runtime.getRuntime().addShutdownHook(hook); 
      Alpha.main(args); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Nice. Nigdy nie używałam haków zamykających jako mechanizmu kontynuacji. –

+0

Świetna odpowiedź .. Dzięki dużo Vlad ... :-) – coolgokul

+0

Nie ma za co. – Vlad

2

(Idealnie, nic nie jest częścią modułu API publicznych powinny niczego, co wywołuje exit kiedykolwiek zrobić, a metoda klasy main powinny być tylko niewielka podkładka, która wywołuje coś innego, co robi prawdziwa praca przed produkcją prawidłowego kodu wyjścia.)

Mimo to, jeśli chcesz, aby zapobiec System.exit można zarejestrować SecurityManager który konwertuje wywołań System.exit język SecurityException s lub Error s.

System.exit:

rzuca

SecurityException - jeśli menedżer bezpieczeństwa istnieje, a jego metoda checkExit nie pozwala wyjść z określonym statusie.

Coś

System.setSecurityManager(new SecurityManager() { 
    @Override 
    public void checkExit(int exitCode) throws SecurityException { 
    throw new SecurityException("stop that"); 
    } 
}); 

Następnie metoda, która dzwoni główne metody można po prostu złapać i tłumić że SecurityException. Możesz uczynić go bardziej wytrzymałym, tworząc własne, a następnie rzucając to i tylko je tłumiąc.

Uważam, że jest to bardzo przydatne w zapobieganiu nieuczciwemu raportowaniu wyników przez biegaczy testowych, gdy testowany biegun jest exit ed przez testowany kod z zerowym kodem wyjścia.

+0

Hm. Nie mogę się zdecydować, co o tym myślę - nie znoszę używać SecurityManagera do robienia rzeczy niezwiązanych z bezpieczeństwem, ale jest to rodzaj eleganckiego hacka. –

+1

@CharlieMartin, zgadzam się, że to hack. Jest dość odporny na ataki hakerskie, a niektóre obawy, rzetelność opinii na temat testu biegacza, uzasadniają to IMO. Są jednak oczywiście problemy - sama obecność "SecurityManager" może łaskotać subtelne błędy w kodzie biblioteki i może wpływać na sposób, w jaki VM optymalizuje rzeczy. –

+0

Cóż, i przegłosowałem to. Nadal nie zdecydowałem, co o tym myślę. –

1

Naprawdę, jedynym rozwiązaniem jest pozbycie się wywołania System.exit(). Właśnie dlatego System.exit() jest zły. Dobrym sposobem na ich zastąpienie jest zgłoszenie wyjątku - możesz dodać do systemu procedurę obsługi wyjątków (zajrzyj do dodawania ich do ThreadGroups, aby dodać jedną dla każdej ścieżki wyjątku), a następnie zdecyduj, co chcesz zrobić.

0

System.exit(0) kończy aktualnie uruchomioną wirtualną maszynę Java. Zamyka całą aplikację na maszynie wirtualnej, a nie tylko aplikację, która wywołuje System.exit(0).Musisz myśleć alternatywnie o swojej funkcjonalności. Oto link na ten temat. System.exit usage

Powiązane problemy