Java > Java Build Tools > Gradle > Gradle Build Automation

Creating a JAR File with Gradle

This snippet illustrates how to configure Gradle to create a JAR (Java Archive) file containing your compiled Java code. It includes setting the manifest attributes, such as the main class, which is essential for creating executable JARs.

build.gradle File with JAR Task Configuration

This `build.gradle` file extends the previous example by adding configuration for creating a JAR file. * `plugins { id 'java' }`: Applies the Java plugin. * `group = 'com.example'`: Defines the group ID. * `version = '1.0-SNAPSHOT'`: Sets the version. * `repositories { mavenCentral() }`: Specifies the Maven Central repository. * `dependencies { ... }`: Declares dependencies, including Apache Commons Lang. * `tasks.jar { ... }`: Configures the `jar` task, which is responsible for creating the JAR file. * `manifest { ... }`: Defines the manifest attributes. * `'Main-Class': 'com.example.Main'`: Sets the main class to `com.example.Main`. This is crucial for creating an executable JAR. * `'Implementation-Version': version`: Sets the implementation version in the manifest. * `from { ... }`: Specifies the files to include in the JAR. * `configurations.runtimeClasspath.collect { ... }`: Collects all runtime dependencies and adds them to the JAR. This handles adding dependency classes into the jar file. * `duplicatesStrategy = DuplicatesStrategy.EXCLUDE`: Addresses potential duplicate files by excluding them. Prevents errors during JAR creation when duplicate files exist within the dependencies.

plugins {
    id 'java'
}

group = 'com.example'
version = '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.apache.commons:commons-lang3:3.12.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}

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

task hello {
    doLast {
        println 'Hello, Gradle!'
    }
}

tasks.jar {
    manifest {
        attributes(
            'Main-Class': 'com.example.Main',
            'Implementation-Version': version
        )
    }
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

Concepts Behind the Snippet

The `jar` task is a standard task provided by the Java plugin. The manifest is a special file within the JAR that contains metadata about the archive. The `Main-Class` attribute tells the JVM which class to execute when the JAR is run. `runtimeClasspath` is a configuration that includes all dependencies needed to run the application.

Real-Life Use Case

You would use this configuration to create a self-contained executable JAR file that can be easily distributed and run on any machine with Java installed. This is common for deploying command-line applications or microservices.

Best Practices

  • Specify the `Main-Class` attribute: Always set the `Main-Class` attribute in the manifest for executable JARs.
  • Include runtime dependencies: Ensure that all runtime dependencies are included in the JAR.
  • Handle duplicate files: Use the `duplicatesStrategy` property to handle potential duplicate files.

Interview Tip

Explain the purpose of the JAR manifest and how to configure the `jar` task in Gradle. Be able to discuss the importance of the `Main-Class` attribute and how to handle dependencies in the JAR.

When to Use Them

Use this configuration when you need to package your Java application into a JAR file for distribution or deployment. Executable JARs are especially useful for creating standalone applications that can be run without requiring a separate installation process.

Alternatives

Alternatives to creating JARs include using Docker containers or creating platform-specific installers. Docker containers provide a more isolated and reproducible environment for running applications. Platform-specific installers (e.g., MSI for Windows) can provide a better user experience for desktop applications.

Pros

  • Easy distribution: JAR files are easy to distribute and run on any machine with Java.
  • Self-contained: Executable JARs contain all the necessary code and dependencies to run the application.
  • Standard format: JAR is a standard format for packaging Java applications.

Cons

  • Large size: JAR files can be large if they include many dependencies.
  • Dependency conflicts: Potential for dependency conflicts if different applications use different versions of the same library.
  • Security concerns: JAR files can be vulnerable to security exploits if not properly secured.

FAQ

  • How do I run the JAR file?

    Open a terminal and run the command `java -jar your-application.jar`, replacing `your-application.jar` with the name of your JAR file.
  • What if I don't specify the `Main-Class` attribute?

    If you don't specify the `Main-Class` attribute, the JAR file will not be executable. You can still include the JAR as a dependency in other projects, but you won't be able to run it directly.
  • How do I exclude specific files from the JAR?

    You can use the `exclude` method in the `from` block to exclude specific files or directories. For example, `exclude '**/unused/*'`. Note: the double asterisk 'asteriskasterisk' is needed to tell gradle to use recursive matching (match all directories).