24

Build Application with Gradle - Single Executable Jar with&a...

 4 years ago
source link: https://blog.shrikantjagtap.com/2019/11/build-application-with-gradle-single.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Build Application with Gradle - Single Executable Jar with scripts

Gradlle Build Application
Photo by 贝莉儿 DANIST on Unsplash

In this tutorial, we will learn how to create executable fat Jar with startup scripts.

As you have already known, Gradle is a popular automation tool for building applications. A customized build script can be created using it either in Groovy or Kotlin DSL.
To start with, we will use Gradle’s Application plugin to create executable JVM application build. It implicitly applies the Java plugin and distribution plugin. It packages the application code with dependencies and startup scripts.
First, create a new build script file build.gradle.kts using Intellij editor.
As you have noticed here filename ends with .kts extension which means this script is written using Kotlin DSL.
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.3.50"
}
group = "demo"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}
dependencies {
    implementation(kotlin("stdlib-jdk8"))
}
tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "1.8"
}
Above is the initial script code when the file is created.
Now next step is to add application plugin. To use it add keyword application to plugins block.
plugins {
    kotlin("jvm") version "1.3.50"
    application}
Application plugin compulsorily requires an entry point for the application to be configured i.e. mainClassName.
application {
    mainClassName = "demo.testapp.MainKt"
}
Till now we have configured Application plugin which will generate the distribution but it won't create fatjar/uber executable Jar as we expected. You might think that why do we need fatjar and doing so what is the benefit?
To answer that it creates a single executable Jar which includes application code and all of its dependencies and resources. It also avoids dependencies classpath conflicts and makes distribution management easy.
Now, we are going to use Gradle Shadow Plugin to create fatjar. To use this plugin add below line to plugins block -
plugins {
    kotlin("jvm") version "1.3.50"
    application
    id("com.github.johnrengelman.shadow") version "5.0.0"
}
We can also configure this plugin by specifying extra parameters to task ShadowJar like -
tasks {
    named<ShadowJar>("shadowJar") {
        archiveBaseName.set("demo")
        mergeServiceFiles()
    }
}
Here, we are setting the archive base name as demo. So it will create an executable Jar that starts with the given base name.
mergeServiceFiles — Multiple dependencies may use the same service descriptor file name, to merge such contents in the same output file this function is useful.
To execute our build script use below command -
./gradlew clean installShadowDist
After executing this will create fatjar with name demo-1.0-SNAPSHOT-all.jar in the directory “./build/install/testapp-shadow/lib/”
and two startup scripts in the directory “./build/install/testapp-shadow/bin/”
testapp — startup for unix systems.
testapp.bat — startup script for windows systems.
As we have reached the end of this tutorial, I hope, this is helpful.

Full code for build.gradle.kts script file for your reference —

import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.3.50"
    application
    id("com.github.johnrengelman.shadow") version "5.0.0"
}
group = "demo"
version = "1.0-SNAPSHOT"

application {
    mainClassName = "demo.testapp.MainKt"
}
repositories {
    mavenCentral()
}
dependencies {
    implementation(kotlin("stdlib-jdk8"))
}
tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "1.8"
}
tasks {
    named<ShadowJar>("shadowJar") {
        archiveBaseName.set("demo")
        mergeServiceFiles()
    }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK