Przechywcenie zdarzenia "kill"

0

Witam.
Mój problem polega na:
Napisałem demona, który musi działać nieprzerwanie. Korzysta on z różnych zasobów do sterowania centralami jednak cały mechanizm jest bardzo niestabilny z powodu np problemów z siecią, obciążeniem bazy itp. Jest możliwość w javie, aby przechwycić zdarzenie gdy jvm od programu jest niszczone i w tym momencie uruchomić ponownie ten sam program?

0

Hmm...jedyne co przychodzi mi na myśl to wywołac Twój program główny z innego programu (programu wywołującego) javy przez :

proc = Runtime.getRuntime().exec(i tu Twój program główny czyli jakieś java -jar i Twój jar)

wtedy masz dostęp do:

BufferedReader error = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));

wtedy widzisz to co leci w konsoli Twojego programu głównego lub ewentulane błędy. Kiedy pojawi CI się JVM crash lub inne ustrojstwo kończaće prace programu to bedziesz to widział w error/input - mozesz to rozpoznawać i uruchamiac Twój program główny od nowa...taka niekończaca sie pętla wywoływania w przypadku wykrycia JVM crash.

EDIT 1
Program wywołujacy przy wywołaniu sam się zatrzyma i bedzie czekał na zakończenie programu głównego wiec nawet nie trzeba watków etc.

EDIT 2

Moze sie tak stać ze nikiedy nie bedziesz chciał by program wywołujacy czekał na odpowiedz programu głównego-wtedy po wywołaniu Runtime... dajesz proc.exitValue();

4

Ja bym się zastanowił nad użyciem takiej konstrukcji:

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(){
public void run(){
   Runtime.getRuntime().exec("tu twój skrypt do uruchamiania");
}
}));

Shutdownhook to całkiem przyzwoite rozwiązanie, które powinno wystarczyć w tym przypadku.

0

@Koziołek

Ano nie wiedziałem, że tak można-oczywiście Twoje rozwiązanie jest bardziej eleganckie i pewne:)

0

Wszystko idealnie jednak gdy wysypie jvm to nie jest wywoływany ten wątek. Domyślam się, że ten element może tylko zabezpieczyć metoda lipkersona?

0

@zabok, nie też nie. Jeżeli składa się JVM za pomocą kill -9 to nie ruszy nic. po prostu był JVM i nie ma JVM. Jedyna pewna rzecz to napisać sobie czujkę w C, która by biegała po liście procesów i na podstawie nazw podnosiła procesy. Pod linuxem można zrobić to: http://groups.google.com/group/pl.comp.os.linux/browse_thread/thread/668348574e9145e6 i uruchomić program jako demona w trybie "respawn". Windows potrafi śledzić listę usług systemowych i w razie czego je uruchamiać.

0

Ok dzięki

0

@Koziołek

Nie mylisz się?
Wg mnie za każdym razem kiedy powołujesz do życia program javowy to powołuje się też JVm. Gdyby tak było to jeden program wysypywałby 10 innych. Nie mam możliwosći sprawdzić - ale przy pierwszej wolnej chwili zweryfikuje:)

0

@lipkerson, w jakim sensie? Bo jeżeli mamy na każdy program osobny JVM (domyślnie i w praktyce) to śledzenie listy procesów jest całkiem dobrym rozwiązaniem. Jeszcze lepszym jest napisanie czegoś w rodzaju managera za pomocą którego będą uruchamiane programy jako osobne instancje JVM.
Mamy coś takiego w pracy. W oryginale to była maszyna COBOLa, a po migracji chcieliśmy mieć funkcjonalność podglądu poszczególnych programów. Działa sobie zatem menadżer uruchamiani, który wpisuje do bazy informacje m.n. o parametrach czy PID programu. Następnie podgląd (napisany w C) bierze te dane i przekazuje operatorom. Z poziomu podglądu można, przynajmniej w teorii, ubić dowolny proces JVM. W praktyce jakoś nigdy tego nie zaimplementowali.

0

@Koziołek i autor - w końcu miałem chwilę czasu i...mój sposób działa:)

Mam jara w którym jest tylko to:

package wywalasie;

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Object[] o = null;

        while (true) {
            o = new Object[]{o};
        }

    }
}

Powoduje to piekny JVM cracsh na amen do loga:)

A potem mam wywołanie z innej aplikacji:


package wywolywacz;


import java.io.*;

public class Main {


    public static void main(String[] args) {

        Process proc;
        Runtime rt = Runtime.getRuntime();
        String line;
        String errorLine;
        while (true) {
            try {
                Process p = Runtime.getRuntime().exec("java -jar \"" + "c:/Test" + "\\WywalaSie.jar\"");
                BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));

                BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));

                while ((line = input.readLine()) != null) {
                    System.out.println(line);
                }
                input.close();

                while ((errorLine = error.readLine()) != null) {
                    System.out.println(errorLine);
                }
                error.close();


            } catch (Exception e) {
                System.out.println(e);
            }

        }



    }
}
 

I działa - jak jest JVM crash to uruchamia na nowo - tutaj bez filozofii jest while(true) ale do problemu autora jest to rozwiązanie.

EDIT: Czemu nie wyświetla jako kod tylko traktuje jako zwykły tekst (forum)-przecież dałem znaczniki:/

0
lipkerson napisał(a)

EDIT: Czemu nie wyświetla jako kod tylko traktuje jako zwykły tekst (forum)-przecież dałem znaczniki:/

Hmm

class Dupa {
  void dupa()
  {
    int dupa = 3;
  }
}

widocznie trzeba < code=java >

1 użytkowników online, w tym zalogowanych: 0, gości: 1