Running a Batch File with ProcessBuilder

5 years ago by in Articles, Process Tagged: , , , ,

Java 5 provided a simple way to execute system commands and programs using the ProcessBuilder (Java Doc). In this short article we will see how we can invoke a batch file from Java and how we can interact with it.

All code listed below is available at: http://java-creed-examples.googlecode.com/svn/process/RunBatchFile/. Most of the examples will not contain the whole code and may omit fragments which are not relevant to the example being discussed. The readers can download or view all code from the above link.

Example of ProcessBuilder

Let assume that we have a batch file called: process.bat located within the directory batch. Therefore, the relative path to this batch file is: batch\process.bat. The batch file is listed below.

echo Hello: %1

echo %message%

dir

The process.bat performs three things.

  1. Prints “Hello: <the-first-argument>
  2. Prints the environment variable with the name message
  3. List all files under the current working directory

This batch file does nothing of interest but it highlights how we can interact with the underlying operating system. To make things a little bit more interesting, we want this batch file to run as if it is in the directory work. Finally, we want to document/log any output produced into a file located within the output directory.

The following example performs just this.

package com.javacreed.examples.process.part1;

import java.io.File;

public class Main {

  public static void main(final String[] args) throws Exception {
    // The batch file to execute
    final File batchFile = new File("batch\\process.bat");

    // The output file. All activity is written to this file
    final File outputFile = new File(String.format("output\\output_%tY%<tm%<td_%<tH%<tM%<tS.txt",
        System.currentTimeMillis()));

    // The argument to the batch file. 
    final String argument = "Albert Attard";

    // Create the process
    final ProcessBuilder processBuilder = new ProcessBuilder(batchFile.getAbsolutePath(), argument);
    // Redirect any output (including error) to a file. This avoids deadlocks
    // when the buffers get full. 
    processBuilder.redirectErrorStream(true);
    processBuilder.redirectOutput(outputFile);

    // Add a new environment variable
    processBuilder.environment().put("message", "Example of process builder");

    // Set the working directory. The batch file will run as if you are in this
    // directory.
    processBuilder.directory(new File("work"));

    // Start the process and wait for it to finish. 
    final Process process = processBuilder.start();
    final int exitStatus = process.waitFor();
    System.out.println("Processed finished with status: " + exitStatus);
  }
}

Let us understand what is happening here.

  1. We started by defining two files, the batch file being executed and the output file. Any output produced by the batch file being normal output or error will go to this file. This is quite convenient as before, we had to create two threads that continuously empty both output buffers (which used to cause deadlock if not done properly).
        // The batch file to execute
        final File batchFile = new File("batch\\process.bat");
    
        // The output file. All activity is written to this file
        final File outputFile = new File(String.format("output\\output_%tY%<tm%<td_%<tH%<tM%<tS.txt",
            System.currentTimeMillis()));
    
  2. Next we create our ProcessBuilder. We are passing two parameters to the ProcessBuilder‘s constructor: the batch file absolute path and the arguments to be passed to the batch file. Different from the Runtime‘s exec() (Java Doc) method, all program parameters should be passed as a separate String object.
        // The argument to the batch file. 
        final String argument = "Albert Attard";
    
        final ProcessBuilder processBuilder = new ProcessBuilder(batchFile.getAbsolutePath(), argument);
    
  3. We then modified the environment variables for this process, by adding a new one named message. The batch file uses the environment variable to simple print its value. In reality, this can be set to anything and we can even modify existing ones such as the user home directory for example.
        // Add a new environment variable
        processBuilder.environment().put("message", "Example of process builder");
    
  4. One of the requirements was to run the batch file from within a specific working directory different from that where the batch file is. This is achieved by setting the working directory.
        // Set the working directory. The batch file will run as if you are in this
        // directory.
        processBuilder.directory(new File("work"));
    
  5. Finally we run our process and wait for it to finishes and print the status code received. When all goes well we get a 0 otherwise we get an error number.
        // Start the process and wait for it to finish. 
        final Process process = processBuilder.start();
        final int exitStatus = process.waitFor();
        System.out.println("Processed finished with status: " + exitStatus);
    

As we saw in this article, running a batch file from Java is quite easy with ProcessBuilder. We tried various combinations in order to capture as many things as possible making this example small but handy.

Albert Attard

Albert Attard is a Java passionate and technical lead at a research group. You can find him on . Over the past years Albert worked on various Java projects including traditional server/client applications, modular applications, large data handling applications and concurrent data manipulation applications to name a few. He has a BSc degree from the University of London (Homepage) and an MSc Information Security with the same university. His MSc thesis (Book) received the 2012 SearchSecurity.co.UK award (Website).

7 Responses to “Running a Batch File with ProcessBuilder”


Dibakar
December 2, 2013 Reply

Thanks for sharing the knowledge. The processBuilder.directory(new File("work")); step helped me resolve an issue I was facing with invoking a batch file containing spaces in its path with Java 1.7 u 21.

Albert Attard Albert Attard
December 2, 2013 Reply

I am glad you found it useful.

Annonymous
April 21, 2014 Reply

Very good navigation on the site. Appreciative.

Vijay Inani
February 24, 2015 Reply

Man .. thnx for the post … really helped me solve the space issue with : processBuilder.directory(new File(“work”));

I had searched everywhere on the internet. There was no help from anywhere. U did it .. thnx.

Albert Attard Albert Attard
February 26, 2015 Reply

I am glad that this post helped you.

Charles Thomas
September 23, 2015 Reply

I followed your example to create a batch file that included the “cls” command. I wrote a Groovy script to run the ProcessBuilder. The ProcessBuilder executed other commands in the batch file, but it did not clear the screen.

The batch file contains:
—————————————————————————–Start of bat file
echo “Inside clear.bat”
dir C:\TEMP
echo “Finishing up inside clear.bat about to execute cls”
cls
———————————————————————————–End of bat file

The Groovy script that calls the ProcessBuilder contains:
——————————————————————————————Start of script
def File batchFile = new File(“clear.bat”)
def File outputFile = new File(String.format(“output_%tY%<tm%<td_%<tH%<tM%echo “Inside clear.bat”
“Inside clear.bat”
C:\ARGO\ArgoMatch\bin>dir C:\TEMP
Volume in drive C has no label.
Volume Serial Number is E42B-28E5
Directory of C:\TEMP
11/19/2014 11:42 AM .
11/19/2014 11:42 AM ..
06/25/2014 03:06 PM 49 myfile.txt
1 File(s) 49 bytes
2 Dir(s) 406,751,617,024 bytes free
C:\ARGO\ArgoMatch\bin>echo “Finishing up inside clear.bat about to execute cls”
“Finishing up inside clear.bat about to execute cls”

C:\ARGO\ArgoMatch\bin>cls
FF
———————————————————————————— End of output file
Is there a way to clear the screen?

Albert Attard Albert Attard
September 26, 2015 Reply

Hi,

I am not sure what you want to clear. The process builder reads whatever is written to the command prompt. Therefore if a program writes something to the command prompt, then the process builder will read this. I am not sure it is possible to clear what you have already read. If the command you are running produces two lines, the process builder will read them (or better consume them). That cannot be cleared.

Leave a Comment


Time limit is exhausted. Please reload the CAPTCHA.