1. Introduction
Building a Kotlin library using Gradle is an essential skill for any developer aiming to create reusable components.
In this tutorial, we’ll walk through creating a Kotlin library, from initial setup to publishing the library for others to use. By the end, we’ll have the knowledge to set up, build, and distribute a Kotlin library using Gradle.
2. Setting up the Kotlin Library
First, we need to initialize a new Kotlin project using Gradle. Gradle will handle the build process, dependency management, and packaging of our Kotlin library. Therefore, let’s create and configure a new project for Kotlin development.
After Gradle is installed, we’ll create a new Kotlin project using Gradle. We can do this by running the gradle init command in the terminal:
gradle init
Additionally, let’s follow the interactive prompt as shown:
> Select type of build to generate:
1: Application
2: Library
3: Gradle plugin
4: Basic (build structure only)
Enter selection (default: Application) [1..4]: 2
> Select implementation language:
1: Java
2: Kotlin
3: Groovy
4: Scala
5: C++
6: Swift
Enter selection (default: Java) [1..6]: 2
> Enter target Java version (min: 7, default: 21): 21
> Project name (default: gradle-library): gradle-library
> Select build script DSL:
1: Kotlin
2: Groovy
Enter selection (default: Kotlin) [1..2]: 1
> Select test framework:
1: kotlin.test
2: JUnit Jupiter
Enter selection (default: kotlin.test) [1..2]: 2
> Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]: no
The key selections here are:
- Type of Build: Library (sets up a reusable library project)
- Implementation Language: Kotlin (chooses Kotlin as the primary programming language)
These two selections lay the foundation for configuring the project as a Kotlin-based library, with further options like Java version, test framework, and build script DSL.
This command generates the basic structure of a Kotlin library, including the build.gradle.kts file, which contains the project’s Gradle configurations.
3. Understanding the Generated build.gradle.kts Configuration
When we initialize our Kotlin library project with gradle init, the setup generates a basic build.gradle.kts file that includes several key configurations. Each part plays a role in building our Kotlin library, managing dependencies, and ensuring compatibility. Let’s examine the components generated in this file.
3.1. Plugins Section
The generated build file sets up the Kotlin and java-library plugins as the starting point of our project:
plugins {
alias(libs.plugins.kotlin.jvm)
`java-library`
}
Here, java-library enables the distinction between public dependencies, declared with api(), and internal dependencies, declared with implementation(), improving encapsulation and reducing potential conflicts in consuming projects.
3.2. Repositories Section
Gradle adds the mavenCentral() repository by default, making it easy to access a wide range of dependencies:
repositories {
mavenCentral()
}
By including mavenCentral(), we tell our build to attempt to download any dependencies from the Maven Central public artifact repository.
3.3. Dependencies Section
The initialization script includes JUnit Jupiter dependencies since we selected that as the test framework:
dependencies {
testImplementation(libs.junit.jupiter)
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
3.4. Java Toolchain
Gradle also configures the Java toolchain to specify the Java version we picked during the interactive setup:
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
3.5. Test Task Configuration
Additionally, the Test task configures our build to use the JUnit Platform, since we picked it during the initial prompts:
tasks.named<Test>("test") {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}
Finally, with this base understanding of the generated build file, we can build our library.
4. Writing the Library Code
Now that our project and dependencies are configured, let’s implement a utility function that leverages kotlinx-datetime as part of the library’s public API.
First, let’s declare kotlinx-datetime dependency in the dependencies block using api():
dependencies {
api("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
}
*By using api(), we also ensure that this dependency is part of our library’s public API and included as a transitive dependency*. This setup allows consumers to work directly with this dependency without including it themselves. This is important because our library will expose classes from this dependency in our public contract.
For our example, let’s create a function that adds a specified number of days to a given date. This function takes a LocalDate as input and returns a new LocalDate after the specified period has been added:
fun addDaysToDate(date: LocalDate, daysToAdd: Int): LocalDate {
val period = DatePeriod(days = daysToAdd)
return date.plus(period)
}
In this function, addDaysToDate() accepts a LocalDate as a parameter and returns a new LocalDate after adding the specified number of days. Since kotlinx-datetime is declared with api(), the LocalDate type is accessible to any project using this library.
5. Packaging the Library
Once we’ve written our Kotlin library and validated its functionality with tests, the next step is to package it for sharing and publication. Gradle makes this process easy by allowing us to configure tasks to generate a JAR (Java ARchive) file.
5.1. Configure the jar Task
Gradle’s Jar task packages our library as a JAR file. We’ll configure the Jar task to customize how the final artifact is created:
tasks.withType<Jar> {
manifest {
attributes["Implementation-Title"] = "My Kotlin Library"
attributes["Implementation-Version"] = "1.0.0"
}
}
In this Kotlin DSL configuration, we ensure that the JAR file includes metadata about our library, such as its name and version. By default, our main Kotlin source sets will also be included in the artifact.
5.2. Generate the JAR
We’ll generate the JAR file by running the following command:
gradle jar
As a result, the final JAR file will be located in the build/libs directory. It can be used as a library by importing it into other projects.
6. Publishing the Library
After building our Kotlin library, we may want to publish it to a repository for reuse. In this section, we’ll specifically configure Gradle to publish our library to a local or private Maven repository.
6.1. Publishing to a Local Maven Repository
First, we apply the maven-publish plugin and set up the publishing configuration in the build.gradle.kts file. So let’s first configure the plugin to publish our library to the local Maven repository:
plugins {
`maven-publish`
}
publishing {
publications {
create<MavenPublication>("mavenJava") {
from(components["java"])
groupId = "com.example"
artifactId = "my-kotlin-library"
version = "1.0.0"
}
}
repositories {
mavenLocal()
}
}
Specifically, we apply the maven-publish plugin and define a MavenPublication named mavenJava, specifying the groupId, artifactId, and version to identify our library. Moreover, the repositories block is configured to publish to the local Maven repository.
6.2. Publishing to a Remote Maven Repository
We can also publish the library to a remote Maven repository by modifying the repositories() block with the repository URL and credentials. Additionally, we’ll handle authentication by retrieving the repository credentials from environment variables:
repositories {
maven {
name = "PrivateRepo"
url = uri("https://private-repo.company.com/repository/maven-releases/")
credentials {
username = System.getenv("REPO_USER") ?: ""
password = System.getenv("REPO_PASSWORD") ?: ""
}
}
}
6.3. Publish the Library
Once the configuration is complete, we can publish the library by running the following command:
gradle publish
After running this command while targeting the local Maven repository, we’ll find the generated artifact in the ~/.m2/repository/com/example/my-kotlin-library/1.0.0/ directory. The folder contains the compiled JAR file and accompanying metadata files, thus making the library available for other local projects to use as a dependency:
~/.m2/repository/com/example/my-kotlin-library/1.0.0/
├── my-kotlin-library-1.0.0.jar
├── my-kotlin-library-1.0.0.module
└── my-kotlin-library-1.0.0.pom
If the configuration includes a remote repository, running gradle publish also publishes the library to that remote repository, making it accessible to other developers or projects. This flexibility allows the same publishing setup for local and remote distribution.
7. Conclusion
In this article, we built a Kotlin library from scratch using Gradle. Specifically, we covered the steps for setting up the project, writing the core functionality, adding unit tests, packaging the library, and publishing it to a Maven repository. As a result, we can now create and distribute Kotlin libraries.