# Building Java Applications Sample {#header}

version 9.4.0  
Contents

* [What you'll build](#what_youll_build)
* [What you'll need](#what_youll_need)
* [Create a project folder](#create_a_project_folder)
* [Run the init task](#run_the_init_task)
* [Review the project files](#review_the_project_files)
* [Run the application](#run_the_application)
* [Bundle the application](#bundle_the_application)
* [Publish a Build Scan](#publish_a_build_scan)
* [Summary](#summary)
* [Next steps](#next_steps)  
* [Groovy DSL](zips/sample_building_java_applications-groovy-dsl.zip)

* [Kotlin DSL](zips/sample_building_java_applications-kotlin-dsl.zip)

|---|-------------------------------------------------------------------------------------------------------|
|   | You can open this sample in an [IDE that supports Gradle](../userguide/gradle_ides.html#gradle_ides). |

This guide demonstrates how to create a Java application with Gradle using `gradle init`. You can follow the guide step-by-step to create a new project from scratch or download the complete sample project using the links above.  

## [What you'll build](#what_youll_build) {#what_youll_build}

You'll generate a Java application that follows Gradle's conventions.  

## [What you'll need](#what_youll_need) {#what_youll_need}

* A text editor or IDE - for example [IntelliJ IDEA](https://www.jetbrains.com/idea/download/)

* A Java Development Kit (JDK), version 8 or higher - for example [AdoptOpenJDK](https://adoptopenjdk.net/)

* The latest [Gradle distribution](https://gradle.org/install)

## [Create a project folder](#create_a_project_folder) {#create_a_project_folder}

Gradle comes with a built-in task, called `init`, that initializes a new Gradle project in an empty folder. The `init` task uses the (also built-in) `wrapper` task to create a Gradle wrapper script, `gradlew`.  
The first step is to create a folder for the new project and change directory into it.  

```
$ mkdir demo
$ cd demo
```

## [Run the init task](#run_the_init_task) {#run_the_init_task}

From inside the new project directory, run the `init` task using the following command in a terminal: `gradle init`. When prompted, select the `1: application` project type and `1: Java` as the implementation language. Next you can choose the DSL for writing buildscripts - `1 : Kotlin` or `2: Groovy`. For the other questions, press enter to use the default values.  
The output will look like this:  

```
$ gradle init

Select type of build to generate:
  1: Application
  2: Library
  3: Gradle plugin
  4: Basic (build structure only)
Enter selection (default: Application) [1..4] 1

Select implementation language:
  1: Java
  2: Kotlin
  3: Groovy
  4: Scala
  5: C++
  6: Swift
Enter selection (default: Java) [1..6] 1

Enter target Java version (min: 7, default: 21):

Project name (default: demo):

Select application structure:
  1: Single application project
  2: Application and library project
Enter selection (default: Single application project) [1..2] 1

Select build script DSL:
  1: Kotlin
  2: Groovy
Enter selection (default: Kotlin) [1..2]

Select test framework:
  1: JUnit 4
  2: TestNG
  3: Spock
  4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4]

Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]

BUILD SUCCESSFUL
1 actionable task: 1 executed
```

The `init` task generates the new project with the following structure:  

    ├── gradle (1)
    │   ├── libs.versions.toml (2)
    │   └── wrapper
    │       ├── gradle-wrapper.jar
    │       └── gradle-wrapper.properties
    ├── gradlew (3)
    ├── gradlew.bat (3)
    ├── settings.gradle.kts (4)
    └── app
        ├── build.gradle.kts (5)
        └── src
            ├── main
            │   └── java (6)
            │       └── demo
            │           └── App.java
            └── test
                └── java (7)
                    └── demo
                        └── AppTest.java

    ├── gradle (1)
    │   ├── libs.versions.toml (2)
    │   └── wrapper
    │       ├── gradle-wrapper.jar
    │       └── gradle-wrapper.properties
    ├── gradlew (3)
    ├── gradlew.bat (3)
    ├── settings.gradle (4)
    └── app
        ├── build.gradle (5)
        └── src
            ├── main
            │   └── java (6)
            │       └── demo
            │           └── App.java
            └── test
                └── java (7)
                    └── demo
                        └── AppTest.java

|-------|----------------------------------------------------|
| **1** | Generated folder for wrapper files                 |
| **2** | Generated version catalog                          |
| **3** | Gradle wrapper start scripts                       |
| **4** | Settings file to define build name and subprojects |
| **5** | Build script of `app` project                      |
| **6** | Default Java source folder                         |
| **7** | Default Java test source folder                    |

You now have the project setup to build a Java application.  

## [Review the project files](#review_the_project_files) {#review_the_project_files}

The `settings.gradle(.kts)` file has two interesting lines:  
settings.gradle.kts  

    rootProject.name = "demo"
    include("app")

settings.gradle  

    rootProject.name = 'demo'
    include('app')

* `rootProject.name` assigns a name to the build, which overrides the default behavior of naming the build after the directory it's in. It's recommended to set a fixed name as the folder might change if the project is shared - e.g. as root of a Git repository.

* `include("app")` defines that the build consists of one subproject called `app` that contains the actual code and build logic. More subprojects can be added by additional `include(...​)` statements.

Our build contains one subproject called `app` that represents the Java application we are building. It is configured in the `app/build.gradle(.kts)` file:  
app/build.gradle.kts  

    plugins {
        application (1)
    }

    repositories {
        mavenCentral() (2)
    }

    dependencies {
        testImplementation(libs.junit.jupiter) (3)

        testRuntimeOnly("org.junit.platform:junit-platform-launcher")

        implementation(libs.guava) (4)
    }

    application {
        mainClass = "demo.App" (5)
    }

    tasks.named<Test>("test") {
        useJUnitPlatform() (6)
    }

app/build.gradle  

    plugins {
        id 'application' (1)
    }

    repositories {
        mavenCentral() (2)
    }

    dependencies {
        testImplementation libs.junit.jupiter (3)

        testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

        implementation libs.guava (4)
    }

    application {
        mainClass = 'demo.App' (5)
    }

    tasks.named('test') {
        useJUnitPlatform() (6)
    }

|-------|-------------------------------------------------------------------------------------|
| **1** | Apply the application plugin to add support for building a CLI application in Java. |
| **2** | Use Maven Central for resolving dependencies.                                       |
| **3** | Use JUnit Jupiter for testing.                                                      |
| **4** | This dependency is used by the application.                                         |
| **5** | Define the main class for the application.                                          |
| **6** | Use JUnit Platform for unit tests.                                                  |

The file `src/main/java/demo/App.java` is shown here:  
Generated src/main/java/demo/App.java  

    /*
     * This source file was generated by the Gradle 'init' task
     */
    package demo;

    public class App {
        public String getGreeting() {
            return "Hello World!";
        }

        public static void main(String[] args) {
            System.out.println(new App().getGreeting());
        }
    }

The generated test, `src/test/java/demo/App.java` is shown next:  
Generated src/test/java/demo/AppTest.java  

    /*
     * This source file was generated by the Gradle 'init' task
     */
    package demo;

    import org.junit.jupiter.api.Test;
    import static org.junit.jupiter.api.Assertions.*;

    class AppTest {
        @Test void appHasAGreeting() {
            App classUnderTest = new App();
            assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
        }
    }

The generated test class has a single *JUnit Jupiter* test. The test instantiates the `App` class, invokes a method on it, and checks that it returns the expected value.  

## [Run the application](#run_the_application) {#run_the_application}

Thanks to the `application` plugin, you can run the application directly from the command line. The `run` task tells Gradle to execute the `main` method in the class assigned to the `mainClass` property.  

```
$ ./gradlew run

> Task :app:run
Hello world!

BUILD SUCCESSFUL
2 actionable tasks: 2 executed
```

|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|   | The first time you run the wrapper script, `gradlew`, there may be a delay while that version of `gradle` is downloaded and stored locally in your `~/.gradle/wrapper/dists` folder. |

## [Bundle the application](#bundle_the_application) {#bundle_the_application}

The `application` plugin also bundles the application, with all its dependencies, for you. The archive will also contain a script to start the application with a single command.  

```
$ ./gradlew build

BUILD SUCCESSFUL in 0s
7 actionable tasks: 7 executed
```

If you run a full build as shown above, Gradle will have produced the archive in two formats for you: `app/build/distributions/app.tar` and `app/build/distributions/app.zip`.  

## [Publish a Build Scan](#publish_a_build_scan) {#publish_a_build_scan}

The best way to learn more about what your build is doing behind the scenes, is to publish a [Build Scan](https://scans.gradle.com). To do so, just run Gradle with the `--scan` flag.  

```
$ ./gradlew build --scan

BUILD SUCCESSFUL in 0s
7 actionable tasks: 7 executed

Publishing a Build Scan to scans.gradle.com requires accepting the Gradle Terms of Service defined at https://gradle.com/terms-of-service.
Do you accept these terms? [yes, no] yes

Gradle Terms of Service accepted.

Publishing Build Scan...
https://gradle.com/s/5u4w3gxeurtd2
```

Click the link and explore which tasks where executed, which dependencies where downloaded and many more details!  

## [Summary](#summary) {#summary}

That's it! You've now successfully configured and built a Java application project with Gradle. You've learned how to:  
* Initialize a project that produces a Java application

* Run the build and view the test report

* Execute a Java application using the `run` task from the `application` plugin

* Bundle the application in an archive

## [Next steps](#next_steps) {#next_steps}

To learn more about how you can further customize Java application projects, check out the following user manual chapters:  
* [Building Java \& JVM projects](../userguide/building_java_projects.html)

* [Java Application Plugin documentation](../userguide/application_plugin.html)

