Building Kotlin Libraries with Gradle
Posted By : Mahipal Singh | 13-Dec-2024
Building Kotlin Libraries with Gradle: A Comprehensive Guide
This guide demonstrates how to create a Kotlin library 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
You'll generate a Kotlin library that follows Gradle's conventions.
What you'll need
- A text editor or IDE - for example IntelliJ IDEA
- A Java Development Kit (JDK), version 8 or higher - for example AdoptOpenJDK
- The latest Gradle distribution
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
From inside the new project directory, run the init
task using the following command in a terminal: gradle init
. When prompted, select the 2: library
project type and 2: Kotlin
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] 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):
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
? ??? libs.versions.toml
? ??? wrapper
? ??? gradle-wrapper.jar
? ??? gradle-wrapper.properties
??? gradlew
??? gradlew.bat
??? settings.gradle.kts
??? lib
??? build.gradle.kts
??? src
??? main
? ??? kotlin
? ??? demo
? ??? Library.kt
??? test
??? kotlin
??? demo
??? LibraryTest.kt
The file src/main/kotlin/demo/Library.kt
is shown here:
Generated src/main/kotlin/demo/Library.kt
/*
* This source file was generated by the Gradle 'init' task
*/
package demo
class Library {
fun someLibraryMethod(): Boolean {
return true
}
}
The generated test, src/test/kotlin/demo/Library.kt
is shown next:
Generated src/test/kotlin/demo/LibraryTest.kt
/*
* This source file was generated by the Gradle 'init' task
*/
package demo
import kotlin.test.Test
import kotlin.test.assertTrue
class LibraryTest {
@Test fun someLibraryMethodReturnsTrue() {
val classUnderTest = Library()
assertTrue(classUnderTest.someLibraryMethod(), "someLibraryMethod should return 'true'")
}
}
The generated test class has a single kotlin.test test. The test instantiates the Library
class, invokes a method on it, and checks that it returns the expected value.
More information about the features the java-library
plugin adds to any JVM library project, such as API and implementation separation, can be found in the Java Library Plugin documentation.
Assemble the library JAR
To build the project, run the build task. You can use the regular gradle command, but when a project includes a wrapper script, it is considered good form to use it instead.
$ ./gradlew build
BUILD SUCCESSFUL in 0s
5 actionable tasks: 5 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.
The first time you run the build, Gradle will check whether or not you already have the required dependencies in your cache under your ~/.gradle
directory. If not, the libraries will be downloaded and stored there. The next time you run the build, the cached versions will be used. The build
task compiles the classes, runs the tests, and generates a test report.
You can view the test report by opening the HTML output file, located at lib/build/reports/tests/test/index.html
.
You can find your newly packaged JAR file in the lib/build/libs
directory with the name lib.jar
. Verify that the archive is valid by running the following command:
$ jar tf lib/build/libs/lib.jar
META-INF/
META-INF/MANIFEST.MF
lib/
lib/Library.class
You should see the required manifest file —MANIFEST.MF
— and the compiled Library
class.
All of this happens without any additional configuration in the build script because Gradle's java-library
plugin assumes your project sources are arranged in a conventional project layout. You can customize the project layout if you wish as described in the user manual.
Congratulations, you have just completed the first step of creating a Kotlin library! You can now customize this to your own project needs.
Customize the library JAR
You will often want the name of the JAR file to include the library version. This is achieved by setting a top-level version
property in the build script:
KotlinGroovy
build.gradle.kts
version = "0.1.0"
Next to the version, other important identity properties of a library are it's name and group. The name is directly derived from the subproject name that represents the library. It's lib
in the example so you probably want to adjust it by changing the name of the lib
folder and the corresponding include(…?)
statement in the settings.gradle(.kts)
file. The group is used to give your library full coordinates when published. You can define it directly in the build script by setting the group
property similar to how you set the version (shown above).
Now run the jar
task:
$ ./gradlew jar
BUILD SUCCESSFUL
2 actionable tasks: 1 executed, 1 up-to-date
You'll notice that the resulting JAR file at lib/build/libs/lib-0.1.0.jar
contains the version as expected.
Another common requirement is customizing the manifest file, typically by adding one or more attributes. Let's include the library name and version in the manifest file by configuring the jar
task. Add the following to the end of your build script:
KotlinGroovy
build.gradle.kts
tasks.jar {
manifest {
attributes(mapOf("Implementation-Title" to project.name,
"Implementation-Version" to project.version))
}
}
To confirm that these changes work as expected, run the jar
task again, and this time also unpack the manifest file from the JAR:
$ ./gradlew jar
$ jar xf lib/build/libs/lib-0.1.0.jar META-INF/MANIFEST.MF
Now view the contents of the META-INF/MANIFEST.MF
file and you should see the following:
META-INF/MANIFEST.MF
Manifest-Version: 1.0
Implementation-Title: lib
Implementation-Version: 0.1.0
Generating Sources JAR
You can easily generate a sources JAR for your library:
KotlinGroovy
build.gradle.kts
java {
withSourcesJar()
}
The additional JAR will be produced as part of the assemble
or build
lifecycle tasks and will be part of the publication. The resulting file is found in lib/build/libs
, with a name using the conventional classifier -sources
.
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. To do so, just run Gradle with the --scan
flag.
class="language-plaintext">$ ./gradlew build --scan
BUILD SUCCESSFUL in 0s
5 actionable tasks: 5 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
That's it! You've now successfully configured and built a Kotlin library project with Gradle. You've learned how to:
- Initialize a project that produces a Kotlin library
- Run the build and view the test report
- Customize the Jar files the build produces
Now you could complete this exercise by trying to compile some Kotlin code that uses the library you just built.
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Mahipal Singh
Mahipal, an adept developer specializing in Android and mobile applications, possesses an extensive grasp of the latest technologies. Proficient in Kotlin, iOS, Flutter, and Android, he excels in Roku app development, API implementation, testing, and deployment. Through his invaluable contributions to various client projects, Mahipal has significantly enhanced his company's standing and values.