Skip to main content

Setting up Gradle with Kotlin DSL, a simple guide

Kotlin is a very a pretty nice adoptive language and user friendly. It really replaced Java from my everyday programming. However, it was not enough. We all know that groovy runs on JVM. So, why do I even need a new language just for my builds? Can't it be Java? So Java is the basic language for the JVM, Kotlin runs on JVM, Groovy runs on JVM and my build system has a separated language from my business logic system. Why?

I was introduced to Gradle with Kotlin accidentally. I never heard of Kotlin DSL in terms of Gradle. I just created a new Spring project and the built file looked kind of strange. After a little Google-ing, everything was clear. Long story short, I removed groovy from my Gradle build tool in my Android project, and replaced it with Kotlin. It shouldn't take more than 15 minutes to do this, but you can struggle with some things in particular.

Note: Kotlin DSL means Kotlin Domain Specific Language. It's just a notation, the name is self descriptive.

 Here are some things to know:

Start with the simplest thing ever: rename your settings.gradle to settings.gradle.kts. It should have less than 5 lines of code:

is just going to be:

Than stick with build.gradle project level. It's shorter (or it has repetitive things). So instead of having a build.gradle just rename the file to build.gradle.kts. There are 2 important things to note here (at least in my case).

Global variables. If you need a variable which is going to be shared across modules and be kept in project level gradle, the ext.kotlin_version = '1.3.61' should just be val kotlinVersion by rootProject.extra { "1.3.61" } and then you can access it by doing this: implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:${rootProject.extra.get("kotlinVersion")}") in your app module.

The custom Clean Task, transforms from:


Don't forget that Kotlin has no idea what ' ' are. Use " " instead. Also, the classpaths, are just becoming simple Kotlin methods with String parameters. So here is my full build.gradle.kts:

So now let's jump to build.gradle module app. I could just paste the whole file (which I would do below), but there are some things to note. For example variables. I know that I it sounds a little stupid, but I never bothered writing variables in  groovy. It was better with just copy-pasting the version 🤦‍♂️. With Kotlin, it's a little more natural to write variables.

Now the plugins transform:


Note that when you have kotlin specific plugins you can just use kotlin() method, otherwise stick to id(). The defaultConfig becomes from:


The buildTypes clause has also a new thing. Instead of:

it becomes:

A now a tricky little thing, KotlinOptions. You would need a getTask()  method to access it. So this:


The rest is just the same. I'm just pasting the full build.gradle.kts (module app) whole file in case I forgot to mention something. There is also a nice guide here in case you have more unmentioned trouble around.

Unfortunately, I am still unable to tell the difference of the build speed because my project is still small. However, I might share it later on my twitter.

Stavro Xhardha

Popular posts from this blog

What I learned from Kotlin Flow API

I used to check the docs and just read a lot about flows but didn't implement anything until yesterday. However, the API tasted really cool (even though some operations are still in Experimental state).Prerequisites: If you don't know RxJava it's fine. But a RxJava recognizer would read this faster.Cold vs Hot streamsWell, I really struggled with this concept because it is a little bit tricky. The main difference between cold and hot happened to be pretty simple: Hot streams produce when you don't care while in cold streams, if you don't collect() (or RxJava-s equivalent subscribe()) the stream won't be activated at all. So, Flows are what we call cold streams. Removing the subscriber will not produce data at all, making the Flows one of the most sophisticated asynchronous stream API ever (in the JVM world). I tried to make a illustration of hot and cold streams: Since I mentioned the word asynchronous this implies that they do support coroutines also. Flows vs…

Modularizing your Android app, breaking the monolith (Part 1)

Inspired by a Martin Fowlers post about Micro Frontends, I decided to break my monolithic app into a modular app. I tried to read a little more about breaking monolithic apps in Android, and as far as I got, I felt confident to share my experience with you. This will be some series of blog posts where we actually try to break a simple app into a modularized Android app.

Note: You should know that I am no expert in this, so if there are false statements or mistakes please feel free to criticize, for the sake of a better development. 

What do you benefit from this approach:
Well, people are moving pretty fast nowadays and delivery is required faster and faster. So, in order to achieve this, modularising Android apps is really necessary.You can share features across different apps. Independent teams and less problems per each.Conditional features update.Quicker debugging and fixing.A feature delay doesn't delay the whole app. As per writing tests, there is not too much difference about…

From Gson to Moshi, what I learned

There is no doubt that people are getting away from GSON and I agree with those reasons too. The only advantage GSON has over other parsing libraries is that it takes a really short amount of time to set up. Furthermore, the most important thing is that Moshi is embracing Kotlin support.

First let's implement the dependency:
implementation("com.squareup.moshi:moshi:1.8.0") It's not a struggle to migrate to Moshi. It's really Gson look-a-like. The only thing to do is annotate the object with @field:Json instead of @SerializedName (which is Gsons way for JS representation):

data class User( //GSON way @SerializedName("name") val name: String, @SerializedName("user_name") val userName: String, @SerializedName("last_name") val lastName: String, @SerializedName("email") val email: String ) data class User( //Moshi way @field:Json(name = "name") val name: String, @field:Json(name = "user_name…