0

I am need to run mvn build on multiple files using one yaml file with different settings for each one.

So, I'll try to describe my problem:

I have the folder with many csv files (C:/folder)

file1.csv
file2.csv
file3.csv
file4.csv
  .
  .
  .

Example of .yaml file

output:
  server:
    url: http:/myserver

  assessment:
    id: 10000
    title: filename

Step 1 - Change the .yaml values

First I am need to set the specific id and title for each file (example for file1)

output:
  server:
    url: http:/myserver

  assessment:
    id: 10001
    title: file1

This is alright, I have created method which changing values in yaml file.

public void changeValueInYaml(int oldId, int newId, String oldTitle, String newTitle) {

//change the values
//save the yaml file

.
.
.

}

Step 2 - Run mvn build

When the .yaml file is saved, I can run the mvn build with settings for specific file

mvn spring-boot:run -Drun.arguments="DcsvFile=C:/folder/file1.csv -DoutputDir=C:/output"

Then I am need to change the values in .yaml file again and run the build for file2, file3 ...

But I want to automatize this job with Java program:

 public static void main(String[] args) {

  File[] files = new File(path).listFiles();
  List fileNames = new ArrayList<String>();

  for (File file : files) {
       if (file.isFile()) {
            fileNames.add(file.getName().replace(".csv", ""));
         }
  }

  int oldId = 10000;
  String oldTitle = "filename";

  for(String fileName : fileNames){

     //Change the value for specific file in yaml
     changeValueInYaml(oldId, ++newId, oldTitle, fileName);
     oldId = newId;
     oldTitle = fileName;

     //Run script via CMD

     String command = "mvn spring-boot:run -Drun.arguments=\"DcsvFile=C:/folder/" + fileName + ".csv -DoutputDir=C:/output\"";

      try
        {
            Runtime.getRuntime().exec("cmd /c start cmd.exe /K " + command);
        }
        catch (Exception e)
        {
            System.out.println("Something is Wrong");
            e.printStackTrace();
        }


       //Here I am need waiting for build ... 
  }

 }

When I run my code, many windows will be displayed at the same time, and I am not sure if each build uses a different configuration from the yaml file. Therefore, I would need a new window to be opened only if the previous one has finished its work.

1 Answers1

1

You can manually wait for the termination of Process using waitFor() method and then execute your command

int processReturnCode = Runtime.getRuntime().exec("...").waitFor();

UPD: Also, you can use CompletableFuture

CompletableFuture<Integer> processFuture = new CompletableFuture<>();
processFuture.thenAcceptAsync(returnCode -> {
    // here you can pass some handler or manually write code
    System.out.printf("Process terminated with %d exit code.\n", returnCode)
});
processFuture.completeAsync(() -> {
     try {
         return Runtime.getRuntime().exec("...").waitFor();
     } catch (Throwable ex) {
         return -1;
     }
 });
  • It is not working ... the windows still opening at the same time –  Mar 29 '20 at 20:58
  • I've forgotten to add #waitFor() method ':D Updated the first answer and added alternative – VoidPointer Mar 29 '20 at 20:59
  • note that waitFor won't work this way. See https://stackoverflow.com/questions/15199119/runtime-exec-waitfor-doesnt-wait-until-process-is-done – lainatnavi Mar 29 '20 at 21:05