import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.*;
public class ProcessRunner implements Runnable {
private ProcessBuilder processBuilder;
private volatile Exception threadException; // Wyjątek przechowywany w tle, musi być volatile
public ProcessRunner(ProcessBuilder processBuilder) {
this.processBuilder = processBuilder;
}
@Override
public void run() {
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
// Logi wyjściowe działające w tle
new Thread(() -> {
String line;
try {
while ((line = reader.readLine()) != null) {
System.out.println("LOG: " + line);
}
} catch (IOException e) {
System.err.println("Error reading log: " + e.getMessage());
}
}).start();
// Odczytywanie błędów i zapisywanie, ale nie przerywamy procesu
String errorLine;
while ((errorLine = errorReader.readLine()) != null) {
System.err.println("ERROR: " + errorLine);
threadException = new RuntimeException("Error detected in process: " + errorLine);
}
int exitCode = process.waitFor(); // Czekamy aż proces się zakończy
if (exitCode != 0) {
threadException = new RuntimeException("Process finished with non-zero exit code: " + exitCode);
}
} catch (IOException | InterruptedException e) {
threadException = e;
}
}
public Exception getThreadException() {
return threadException;
}
}
// Klasa główna
public class MainApp {
public static void main(String[] args) {
// Tworzymy ExecutorService z pulą wątków
ExecutorService executorService = Executors.newFixedThreadPool(2);
// Tworzymy ProcessBuilder dla naszej aplikacji
ProcessBuilder processBuilder = new ProcessBuilder("path_to_exe", "arg1", "arg2");
// Tworzymy obiekt ProcessRunner
ProcessRunner processRunner = new ProcessRunner(processBuilder);
// Składamy zadanie do wykonania w tle
executorService.submit(processRunner);
// Główna pętla, sprawdzająca stan procesu w tle co pewien czas
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(() -> {
Exception e = processRunner.getThreadException();
if (e != null) {
System.err.println("Error caught from process: " + e.getMessage());
// Obsługa błędów, ale proces nadal działa
}
}, 0, 1, TimeUnit.SECONDS); // Sprawdzanie co sekundę
// Proces w tle działa, a główny wątek kontynuuje swoje działanie
System.out.println("Main thread continues while process runs in the background.");
// Upewnij się, że ExecutorService i Scheduler zostaną poprawnie zakończone
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
executorService.shutdown();
scheduler.shutdown();
}));
}
}
Kluczowe punkty rozwiązania:
Proces działa równolegle: ExecutorService uruchamia proces w oddzielnym wątku, a ScheduledExecutorService sprawdza co pewien czas, czy wystąpił błąd.
Raportowanie błędów bez zatrzymywania procesu: Wątek z procesem może raportować błędy, ale nie przerywa swojego działania. Główna pętla (za pomocą ScheduledExecutorService) sprawdza, czy w procesie pojawił się błąd i odpowiednio go obsługuje.
Błędy są zgłaszane w tle: W przypadku wystąpienia błędu, wyjątek jest przechwytywany i można go obsłużyć (np. logować, wysyłać powiadomienia) bez zatrzymywania procesu.
Proces działa niezależnie: Proces działa w tle bez ingerencji w główny wątek. Główny wątek aplikacji może działać normalnie, niezależnie od procesu w tle.
Dodatkowe informacje:
ScheduledExecutorService jest używany do okresowego sprawdzania, czy w procesie pojawił się błąd.
volatile: Zmienna threadException jest oznaczona jako volatile, aby zapewnić poprawną widoczność zmiany wartości między wątkami.
Shutdown: Runtime.getRuntime().addShutdownHook dodaje hook, który zamyka ExecutorService i Scheduler podczas zamykania aplikacji, zapewniając poprawne zakończenie wszystkich wątków.
To podejście spełnia Twoje wymagania: proces działa w tle, błędy są zgłaszane, a proces nie zostaje przerwany w momencie wystąpienia błędu.
Paste Hosted With By Wklejamy.pl