-2

This question is about Java Concurrency. I'm trying to get cmdline to execute another application that takes cmdline arguments in Windows 10 and Server 2012R2. Basically I am trying run the program against 5 files at a time (threadpool is 5). The problem is, I can't get Java to not have more than 5 instances of that application running at a time. It will bassically try and start an instance for every file at one time if not for the Thread.sleep method.

The program i'm trying to launch does return output in cmdline and powershell (I tried that too), so I tried to trick Java into waiting for the instance to fully complete with text and a java.isAlive loop within the lambda, so the process would only finish the lambda once the process self terminates after processing the file it was assigned. None of that worked.

Do I have to write "Process process = Runtime.getRuntime()" within the lambda in a seperate class and create a new object in the lambda instead with the arguments? Any ideas?

                ExecutorService service = Executors.newFixedThreadPool(5);
                File file = new File("SCAP_Hosts/");
                File[] f = file.listFiles();
                for (File x : f) {
                    String y = x.toString();
                    Future<?> result = service.submit(() -> {
                        Process process = Runtime.getRuntime().exec("c:/Software/SCAP Compliance Checker 5.0.2/cscc.exe -o WSoptions.xml -f " + y);
                        try {
                            Thread.sleep(60000);
                            x.delete();
                            } catch (IOException | InterruptedException e) {e.printStackTrace();}
                    });
                    try {Thread.sleep(20000);} catch (InterruptedException e) {e.printStackTrace();}
                }
            } 
            }
            service.shutdown();
            while (true) {
                if (service.isTerminated()) {
                    System.out.println("Program Finished");
                    break;
J T
  • 59
  • 2
  • 6

1 Answers1

2

You did not call any blocking method on Process so the thread does not have to wait for anything and just marks itself ready for a next task.

I suggest you call process.waitFor()

Alexander Pavlov
  • 2,264
  • 18
  • 25
  • 1
    *And* examine the result code. I doubt that command string will execute. – user207421 Sep 02 '19 at 03:20
  • 1
    Spaces in the path smell troubles :) – Alexander Pavlov Sep 02 '19 at 03:21
  • Where would I place the process.waitFor()? Also, spaces work, trust me lol. I made sure to test the command itself in Java and get the output, so I can see that it's running. – J T Sep 02 '19 at 03:26
  • 1
    @JT Have you considered placing it after the `exec()`? Your claim about spaces is not credible. It will try to execute `"C:/Software/SCAP"`, and fail. And unless you called `wItFor()` *amd* checked the result you cannot possibly assert otherwise. Trust me ;-) – user207421 Sep 02 '19 at 03:28
  • 1
    Right after you create it. Also, you may want to use `waitFor(timeout, unit)` to ensure you handle hung processes correctly – Alexander Pavlov Sep 02 '19 at 03:29
  • YUP! I placed it inside the lambda expression and it worked. The reason i never thought of that before, was because I wrote something similar that calls powershell to return some output for me directly and I didn't need to waitFor() for it to keep the processes at the target. THANK YOU! I've been trying to figure this out all day! – J T Sep 02 '19 at 03:35