Call java from another java process to stop it

I have a program with 2 java processes: processA and processB (2 process java.exe not 2 threads). I use the code block below from process A to call processB, this code is wrapped in the RunTask class below

public class RunTask implements Callable<Object> { private String runParams; public String getRunParams() { return runParams; } public void setRunParams(String runParams) { this.runParams = runParams; } @Override public Object call() throws Exception { try { //System.out.println("run:" + runParams); Process procB = Runtime.getRuntime().exec("java -jar processB.jar); DataInputStream ls_in = new DataInputStream(procB.getInputStream()); String ls_str; while ((ls_str = ls_in.readLine()) != null) { System.out.println(ls_str); } } catch (Exception exp) { exp.printStackTrace(); } return null; } } 

and the main class I use a performer

  ExecutorService eservice = Executors.newSingleThreadExecutor(); while (1 == 1) { String stringParams = getFilesNeedToImportAsString(); if (stringParams.trim().isEmpty()) { long l1 = System.currentTimeMillis() - l; System.out.println("all time" + l1 / 1000); System.exit(100); } RunTask runTask = new RunTask(); runTask.setRunParams(SystemInfo.RUN_COMMAND + stringParams); Future<Object> objectFuture = eservice.submit(runTask); while (!objectFuture.isDone()) { System.out.println("waiting the task running"); Thread.sleep(500); } } 

But when an exception occurred in processB, both processes (processA, processB) seem to be stopped, this is the code executed on processB

 public Object call() { try { MutationResult result = mutator.execute(); return "ok"; } catch (Exception exp) { exp.printStackTrace(); System.out.println("error on " + Thread.currentThread().getName() + "failed begin retry " + (++retryCount)); call(); System.out.println(retryCount + " completed"); return "ok"; } } 

If I run processB separately (on the command line), it will never happen, or when this problem occurs, I use taskmanager to kill proceesA (calllee), processB continues to work

Please give me a solution to this problem!

+4
source share
3 answers

You are waiting for the objectFuture isDone method objectFuture isDone . According to the documentation:

isDone: returns true if this task is completed. Termination may be due to a normal termination, exception or cancellation - in all of these cases, this method will return true

By looking at the code in process B when an exception occurs, you again execute call() recursively. I understand that you are doing this as a retry mechanism, but this is a very bad idea for two main reasons: - If the exception persists, you will get a StackOverflowException . - None of the conditions for isDone will be met.

A better alternative would be to determine the maximum number of attempts and try to execute mutator.execute() . If the error persists, then throw and throw and terminate.

Another option is to wait until process B completes for the maximum time after which you cancel the task by calling objectFuture.cancel(true) .

A few comments on processA: In RunTask you are not using runParams , which seem to be some files that need to be imported as a string. In addition, you use readLine() in a DataInputStream , which is an obsolete method. Instead, use an InputStream (e.g. BufferedInputStream ) wrapped in an InputStreamReader and then wrapped in a BufferedReader - then call readLine() on the BufferedReader .

+2
source

One thing that I came across when spawning exec is that if an error occurs and I did not configure the stream to read ErrorStream, then the ErrorStream buffer can fill up, after which everything stops grinding, waiting for me to clear some of the text from ErrorStream buffers. Process B cannot write more about the error until I do this, and process A waits for process B to complete.

The end result of my experience: always tune the stream to read each of InputStream and ErrorStream when you execute exec ().

+1
source

printStackTrace will print a standard error, not a standard error. You will also need to read the standard error (which is difficult: you will need 2 threads, one for each thread) or instead of standard printing ( printStackTrace(System.out) ).

+1
source

All Articles