Generic Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Introduction

In this tutorial, we'll explore the different methods of executing a Java main method using Gradle.

2. Java main Method

There are several ways in which we can run a Java main method with Gradle. Let us look at them closely using a simple program that prints a message to the standard output:

public class MainClass {
    public static void main(String[] args) {
        System.out.println("Goodbye cruel world ...");
    }
}

3. Running with the Application Plugin

The Application plugin is a core Gradle plugin that defines a collection of ready-to-use tasks that help us package and distribute our application.

Let's start by inserting the following in our build.gradle file:

plugins {
    id "application"
}
apply plugin : "java" 
ext {
   javaMainClass = "com.baeldung.gradle.exec.MainClass"
}

application {
    mainClassName = javaMainClass
}

The plugin automatically generates a task called run that only requires us to point it to the main class. The closure at line 9 does exactly that, which allows us to trigger the task:

~/work/baeldung/tutorials/gradle-java-exec> ./gradlew run

> Task :run
Goodbye cruel world ...

BUILD SUCCESSFUL in 531ms
2 actionable tasks: 1 executed, 1 up-to-date

4. Running with the JavaExec Task

Next, let's implement a custom task for running the main method with the help of the JavaExec task type:

task runWithJavaExec(type: JavaExec) {
    group = "Execution"
    description = "Run the main class with JavaExecTask"
    classpath = sourceSets.main.runtimeClasspath
    main = javaMainClass
}

We need to define the main class on line 5 and, additionally, specify the classpath. The classpath is computed from the default properties of the build output and contains the correct path where the compiled class is actually placed.

Notice that in each scenario, we use the fully qualified name, including package, of the main class.

Let's run our example using JavaExec:

~/work/baeldung/tutorials/gradle-java-exec> ./gradlew runWithJavaExec

> Task :runWithJavaExec
Goodbye cruel world ...

BUILD SUCCESSFUL in 526ms
2 actionable tasks: 1 executed, 1 up-to-date

5. Running with the Exec Task

Finally, we can execute our main class using the base Exec task type. Since this option offers us the possibility to configure the execution in multiple ways, let's implement three custom tasks and discuss them individually.

5.1. Running from the Compiled Build Output

First, we create a custom Exec task that behaves similarly to JavaExec:

task runWithExec(type: Exec) {
    dependsOn build
    group = "Execution"
    description = "Run the main class with ExecTask"
    commandLine "java", "-classpath", sourceSets.main.runtimeClasspath.getAsPath(), javaMainClass
}

We can run any executable (in this case java) and pass the necessary arguments for it to run.

We configure the classpath and point to our main class on line 5, and we also add a dependency to the build task on line 2. This is necessary, as we can only run our main class after it is compiled:

~/work/baeldung/tutorials/gradle-java-exec> ./gradlew runWithExec

> Task :runWithExec
Goodbye cruel world ...

BUILD SUCCESSFUL in 666ms
6 actionable tasks: 6 executed

5.2. Running from an Output Jar

The second approach relies on the jar packaging of our small application:

task runWithExecJarOnClassPath(type: Exec) {
    dependsOn jar
    group = "Execution"
    description = "Run the mainClass from the output jar in classpath with ExecTask"
    commandLine "java", "-classpath", jar.archiveFile.get(), javaMainClass
}

Notice the dependency to the jar task on line 2 and the second argument to the java executable on line 5. We use a normal jar, so we need to specify the entry point with the fourth parameter:

~/work/baeldung/tutorials/gradle-java-exec> ./gradlew runWithExecJarOnClassPath

> Task :runWithExecJarOnClassPath
Goodbye cruel world ...

BUILD SUCCESSFUL in 555ms
3 actionable tasks: 3 executed

5.3. Running from an Executable Output Jar

The third way also relies on the jar packaging, but we define the entry point with the help of a manifest property:

jar {
    manifest {
        attributes(
            "Main-Class": javaMainClass
        )
    }
}

task runWithExecJarExecutable(type: Exec) {
    dependsOn jar
    group = "Execution"
    description = "Run the output executable jar with ExecTask"
    commandLine "java", "-jar", jar.archiveFile.get()
}

Here, we no longer need to specify the classpath, and we can simply run the jar:

~/work/baeldung/tutorials/gradle-java-exec> ./gradlew runWithExecJarExecutable

> Task :runWithExecJarExecutable
Goodbye cruel world ...

BUILD SUCCESSFUL in 572ms
3 actionable tasks: 3 executed

6. Conclusion

In this article, we explored the various ways of running a Java main method using Gradle.

Out of the box, the Application plugin provides a minimally configurable task to run our method. The JavaExec task type allows us to run the main method without specifying any plugins.

Finally, the generic Exec task type can be used in various combinations with the java executable to achieve the same results but requires a dependency on other tasks.

As usual, the source code for this tutorial is available over on GitHub.

Generic bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
Comments are closed on this article!