Gradle+Kotlin

create project

You can use initPlugin to create Kotlin application or library from command line with built-in master.

# create kotlin application
gradle init --type kotlin-application

# create kotlin library
gradle init --type kotlin-library

Further follow to master.

plugins

 plugins {
    kotlin("jvm") version "1.4.10" // Gradle 5.4+
    application // to create application
    // ...
}

repositories

In most cases maven central repository will be sufficient. You can add other repositories if necessary.

repositories {
    mavenCentral()
    
    // Bintray's JCenter repository
    jcenter() 
    
    // Spring boot snapshot reopsitory
    maven ("https://repo.spring.io/libs-snapshot")
    // ...
}

artefact

Artefact is specified in usual way.

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

target

Kotlin support different target platforms.

  • jvm - to target the JVM
  • js - to target js
  • multiplatform - to target the JVM (Gradle 6.0+)
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
// ...
tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString()
}
tasks { compileKotlin { kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } }
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
//...
tasks.withType(KotlinCompile) {
    kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { kotlinOptions { jvmTarget = '1.8' // freeCompilerArgs += '-Xjvm-default=compatibility' // freeCompilerArgs += '-include-runtime' } }

To buld a native or android application use kotlin-multiplatform or Android Gradle plugin correspondingly.

app entry point

Suppose application entry point is file Main.kt file with following content:

class Main

fun main(args: Array<String>) {
   // ...
}

Then two files will be generated: Main.class and MainKt.class. We need second as entry point.

application {
    mainClassName = "com.example.MainKt"
}

mix with Java code

You can mix Java and Kotlin code, just add folders with java code to source code paths.

sourceSets.main {
    java.srcDirs("src/main/java", "src/main/kotlin")
}

dependencies

dependencies {
    compile(fileTree(mapOf("dir" to "libs", 
        "include" to listOf("*.jar"))))
    
    // implementation(kotlin("stdlib"))
    
    // if you want extensions for java 8, 
    // like use() function for AutoCloseable
    implementation(kotlin("stdlib-jdk8"))
    
    
    // you can use other test libraries
    testImplementation(kotlin("test-junit"))
    // ...
}

jar

To create executable jar you need

  1. specify entry point in manifest, otherwise you will get error
    no main manifest attribute, in xxx.jar
  2. include kotlin runtime to classpath, otherwise you will get error
    Exception in thread "main" java.lang.NoClassDefFoundError:
    kotlin/jvm/internal/Intrinsics at com.example.MainKt.main(Main.kt)
Code example
tasks {
    withType<Jar> {
        manifest {
            attributes["Main-Class"] = "com.example.MainKt"
        }
        
        from(configurations
            .runtimeClasspath.get()
            .map { if (it.isDirectory) it else zipTree(it) })
    }
}
Code example
jar {
    from {
        String[] include = [
            "kotlin-runtime-${version_kotlin}.jar",
            "kotlin-stdlib-${version_kotlin}.jar"
        ]

        configurations.compile
                .findAll { include.contains(it.name) }
                .collect { it.isDirectory() ? it : zipTree(it) }
    }
}

build.gradle.kts

Code example
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.4.10"
    application
}

repositories {
    mavenCentral()
    // jcenter()
}

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

tasks {
    compileKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
    compileTestKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
}

sourceSets.main {
    java.srcDirs("src/main/java", "src/main/kotlin")
}

application {
    mainClassName = "com.example.MainKt"
}

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", 
        "include" to listOf("*.jar"))))
    compile("org.jetbrains.kotlin:kotlin-stdlib")
    testImplementation(kotlin("test-junit"))
}

tasks {
    withType<Jar> {
        manifest {
            attributes["Main-Class"] = "com.example.MainKt"
        }

        from(configurations
            .runtimeClasspath
            .get()
            .map { if (it.isDirectory) it else zipTree(it) })
    }
}