Executing another java program from our java program [duplicate]

Solution 1:

It isn't clear from the question, but I will assume the other Java program is a command line program.

If this is the case you would use Runtime.exec().

It isn't quite that simple if you want to see what the output of that program is. Below is how you would use Runtime.exec() with any external program, not just a Java program.

First you need a non-blocking way to read from Standard.out and Standard.err

private class ProcessResultReader extends Thread
{
    final InputStream is;
    final String type;
    final StringBuilder sb;

    ProcessResultReader(@Nonnull final InputStream is, @Nonnull String type)
    {
        this.is = is;
        this.type = type;
        this.sb = new StringBuilder();
    }

    public void run()
    {
        try
        {
            final InputStreamReader isr = new InputStreamReader(is);
            final BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null)
            {
                this.sb.append(line).append("\n");
            }
        }
        catch (final IOException ioe)
        {
            System.err.println(ioe.getMessage());
            throw new RuntimeException(ioe);
        }
    }

    @Override
    public String toString()
    {
        return this.sb.toString();
    }
}

Then you need to tie this class into the respective InputStream and OutputStreamobjects.

    try
    {
        final Process p = Runtime.getRuntime().exec(String.format("cmd /c %s", query));
        final ProcessResultReader stderr = new ProcessResultReader(p.getErrorStream(), "STDERR");
        final ProcessResultReader stdout = new ProcessResultReader(p.getInputStream(), "STDOUT");
        stderr.start();
        stdout.start();
        final int exitValue = p.waitFor();
        if (exitValue == 0)
        {
            System.out.print(stdout.toString());
        }
        else
        {
            System.err.print(stderr.toString());
        }
    }
    catch (final IOException e)
    {
        throw new RuntimeException(e);
    }
    catch (final InterruptedException e)
    {
        throw new RuntimeException(e);
    }

This is pretty much the boiler plate I use when I need to Runtime.exec() anything in Java.

A more advanced way would be to use FutureTask and Callable or at least Runnable rather than directly extending Thread which isn't the best practice.

NOTE:

The @Nonnull annotations are in the JSR305 library. If you are using Maven, and you are using Maven aren't you, just add this dependency to your pom.xml.

<dependency>
  <groupId>com.google.code.findbugs</groupId>
  <artifactId>jsr305</artifactId>
  <version>1.3.9</version>
</dependency>

Solution 2:

  • Call the other program's main method (or whatever is the entry point in the other program)

  • or use ProcessBuilder