Quantcast
Channel: Baeldung
Viewing all articles
Browse latest Browse all 4616

Execute a JAR File From a Java Program

$
0
0

1. Introduction

While working on Java projects, we might encounter a situation where we need to run an external JAR (executable JAR) from within the Java program as a separate process and see the output, or we might want to execute a class file with the main method in an external JAR.

In this tutorial, we’ll see how to handle both scenarios and code examples.

2. Execute an Executable JAR

An executable JAR is a type of JAR file that includes a manifest file with the Main-Class attribute set. This attribute points to the class file that should run first (with the main method).

We can run this JAR from the command line using the java -jar <example.jar> command. We can accomplish similar results from a Java program using ProcessBuilder.

The code below demonstrates how we can programmatically run an executable JAR as a separate process and see the output in the console:

@Test
public void givenRunnableJar_whenExecuted_thenShouldRunSuccessfully() {
    Process process = null;
    try {
        String jarFile = new File(Objects.requireNonNull(getClass().getClassLoader()
          .getResource(RUNNABLE_JAR_PATH))
          .toURI()).getAbsolutePath();
        ProcessBuilder processBuilder = new ProcessBuilder("java", "-jar", jarFile);
        processBuilder.redirectErrorStream(true);
        process = processBuilder.start();
        try (InputStream inputStream = process.getInputStream()) {
            byte[] output = inputStream.readAllBytes();
            System.out.println("Output: " + new String(output));
        }
        int exitCode = process.waitFor();
        Assert.assertEquals("Process exited with an unexpected exit code", 0, exitCode);
    } catch (IOException | InterruptedException | URISyntaxException e) {
        Assert.fail("Test failed due to exception: " + e.getMessage());
    } finally {
        if (process != null) {
            process.destroy();
        }
    }
}

This test checks to see if the executable JAR is executed successfully.

Initially, we’re creating a File object by providing the absolute path of the JAR file (executable JAR in this case). The getClass().getClassLoader().getResource(RUNNABLE_JAR_PATH) method gets the resource URL, which we’re ensuring is not null and converting into a URI.

We then set up a command using java -jar, a standard way to execute an executable JAR. Next, we’re using ProcessBuilder to execute the JAR as a new process.

Once the execution is started, we try to capture the program output from the input stream. The output is then converted into a string and printed on the console. It is similar to what we would see if we ran the java –jar command.

After that, we wait for the process to complete using process.waitFor(). If the exit code is zero, it indicates that the execution is successful. If the exit code is a non-zero value, it means that an error occurred during execution, and the test would fail.

3. Executing a Non-executable JAR File

A non-executable JAR file doesn’t have a Main-Class attribute in its manifest file. We have to mention the class with the main method explicitly.

The code below demonstrates how we can programmatically execute a class file in non-executable JAR as a separate process and see the output in the console:

@Test
public void givenNonRunnableJar_whenExecutedWithMainClass_thenShouldRunSuccessfully() {
    Process process = null;
    try {
        String jarFile = new File(Objects.requireNonNull(getClass().getClassLoader()
          .getResource(NON_RUNNABLE_JAR_PATH))
          .toURI()).getAbsolutePath();
        String[] command = { "java", "-cp", jarFile, "com.company.HelloWorld", "arg1", "arg2" };
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        processBuilder.redirectErrorStream(true);
        process = processBuilder.start();  // Start process
        try (InputStream inputStream = process.getInputStream()) {
            byte[] output = inputStream.readAllBytes();
            System.out.println("Output: " + new String(output));
        }
        int exitCode = process.waitFor();
        Assert.assertEquals("Process exited with an unexpected exit code", 0, exitCode);
    } catch (IOException | InterruptedException | URISyntaxException e) {
        Assert.fail("Test failed due to exception: " + e.getMessage());
    } finally {
        if (process != null) {
            process.destroy();  // Ensure cleanup in all Java versions
        }
    }
}

The above test checks if we can execute the main class in the non-runnable jar.

In the beginning, we’re creating a process.waitForobject by providing the absolute path of the JAR file (non-executable JAR in this case).

We then set the execution environment using ProcessBuilder. The redirectErrorStream(true) method merges the error stream with the standard output stream so that we can capture all output in one place.

The command is then executed as a new process with processBuilder.start(). We are capturing the program’s output from the process’s input stream and then converting it to a string to print it on the console. The output is similar to the output we see when we manually run the command.

Finally, with process.waitFor(), we are monitoring the process until it is complete.

If the exit code is zero, the JAR is executed successfully, and if it is a non-zero value, it means there was an error while executing the JAR.

4. Conclusion

In this article, we’ve seen how executing JAR files from a Java program is straightforward. While we don’t need to explicitly mention the class to run the executable JAR, we have to for the non-executable JAR.

We’ve also seen how we can use the ProcessBuilder class for proper stream handling and to execute the jar as a separate process.

And, as always, the source code for the examples can be found over on GitHub.

The post Execute a JAR File From a Java Program first appeared on Baeldung.
       

Viewing all articles
Browse latest Browse all 4616

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>