84

In Kotlin project, what is a proper Gradle script to make sure my classes will be compiled to byte code ver 52 (Java 8)?

For some reason my classes are compiled as ver 50 (Java 6) even though I set up source and target compatibility. At least this is what Idea shows me when I open file from directory build/classes/... after building the project.

My current set up looks like this.

buildscript {
    ext {
        kotlinVersion = '1.0.5-2'
        springBootVersion = '1.4.2.RELEASE'
    }
    repositories { mavenCentral() }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
    }
}

apply plugin: 'kotlin'
apply plugin: 'org.springframework.boot'

tasks.withType(JavaCompile) {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

// I also tried this and it hasn't helped
//sourceCompatibility = 1.8
//targetCompatibility = 1.8

repositories { mavenCentral() }

dependencies {
    compile("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
    compile('org.springframework.cloud:spring-cloud-starter-stream-rabbit')
}

dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:Camden.SR2" } }
nnym
  • 26
  • 1
  • 8
wst
  • 4,040
  • 4
  • 41
  • 59

11 Answers11

108

As Mark pointed out on Debop's answer, you have to configure both compileKotlin and compileTestKotlin. You can do it without duplication this way:

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
  kotlinOptions {
    jvmTarget = "1.8"
  }
}

For a pure Kotlin project, I don't think the options sourceCompatibility and targetCompatibility do anything, so you may be able to remove them.

Ref: https://kotlinlang.org/docs/reference/using-gradle.html#compiler-options

mkobit
  • 43,979
  • 12
  • 156
  • 150
seanf
  • 6,504
  • 3
  • 42
  • 52
  • 5
    I would do this: `org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java` – programaths Jan 06 '19 at 12:25
  • 1
    FYI, don't use `all` use `configureEach` this is the prefered way for task avoidance and will speed up your configuration phase on larger projects – Chris.Jenkins Jul 27 '21 at 18:29
  • 1
    Update for Kotlin 1.8, this is now the preferred syntax (kotlinOptions is [deprecated](https://kotlinlang.org/docs/whatsnew18.html#exposing-kotlin-compiler-options-as-gradle-lazy-properties)): `tasks.withType(KotlinCompile).configureEach { compilerOptions.jvmTarget.set(JvmTarget.JVM_1_8) }` – winne2 Mar 29 '23 at 08:33
77

In case someone uses gradle with kotlin-dsl instead of groovy:

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

// compile bytecode to java 8 (default is java 6)
tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "1.8"
}
guenhter
  • 11,255
  • 3
  • 35
  • 66
40

Kotlin 1.1 in Gradle. in console you have error about inline (your installed compiler is 1.0.x) If run gradle task in IntelliJ IDEA, your code compiled by kotlin 1.1 compiler

compileKotlin {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8

    kotlinOptions {
        jvmTarget = "1.8"
        apiVersion = "1.1"
        languageVersion = "1.1"
    }
}
Debop
  • 1,035
  • 10
  • 9
  • 5
    Looks like you may need to duplicate this in a compileTestKotlin block to also apply this config to test code. If I'm wrong about this, though, I'd like to know about it and why. – Mark Apr 07 '17 at 16:54
  • You are correct. That's because this is configuring only the `compileKotlin` task. It's better to configure all tasks with type `KotlinCompile` to ensure that any existing, or added, tasks that compile Kotlin are configured to use the desired Java version. – Andrew A. Tasso Sep 18 '21 at 01:11
17
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

// JVM target applied to all Kotlin tasks across all subprojects

// Kotlin DSL
tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString()
}

//Groovy
tasks.withType(KotlinCompile) {
    kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8
}
Igor
  • 2,039
  • 23
  • 27
11

In your build.gradle.kts:

    tasks {
        val java = "11"

        compileKotlin { 
           kotlinOptions { jvmTarget = java }
           sourceCompatibility = java
        }
    }

Or like this:

tasks {
    withType<KotlinCompile> { kotlinOptions { jvmTarget = "11" } }
}
Dmitry Kaltovich
  • 2,046
  • 19
  • 21
7

Kotlin 1.0 always produces Java 6 class files. Kotlin 1.1 will support generating Java 8 class files by passing -jvm-target 1.8 to the compiler. See

https://blog.jetbrains.com/kotlin/2016/07/first-glimpse-of-kotlin-1-1-coroutines-type-aliases-and-more/

for a discussion of Java 7/8 support.

Ingo Kegel
  • 46,523
  • 10
  • 71
  • 102
6

Since gradle 6.7 there is so called java toolchain support in gradle which I find easiest to use.

It allows you to configure the JDK to use for this project and will even download the required version if needed.

All you need is a compatible JRE to start gradle and this block in your gradle build file:

kotlin dsl

kotlin {
    jvmToolchain {
        // for gradle kotlin plugin < 1.7:
        (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17))
        // for gradle kotlin plugin >= 1.7:
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

groovy dsl

kotlin {
    jvmToolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

Note: This will update the java compiler settings as well, so you don't need anything else in your build.gradle.kts

Read more about this in the docs:

https://kotlinlang.org/docs/gradle.html#set-custom-jdk-home

https://docs.gradle.org/current/userguide/toolchains.html

hennr
  • 2,632
  • 2
  • 23
  • 26
  • 1
    As per: https://kotlinlang.org/docs/gradle-configure-project.html#gradle-java-toolchains-support, there is even shorter syntax: `kotlin { jvmToolchain(17) }` – nouveu Jun 02 '23 at 07:46
1

For anyone like me who use maven to build mixed code of kotlin and java in intellij , you need to set

<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>

because maven build doesn't respect jvmTarget set in project setting.

happy15
  • 79
  • 1
  • 4
1

thx for seanf's anwser ,but if your DSL kotlin is 1.3.0:

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java).all {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}
leonardosccd
  • 1,503
  • 11
  • 12
  • `kotlin-dsl` was already answered with better syntax at https://stackoverflow.com/a/45994990/627727 – mkobit Feb 18 '19 at 21:01
1

If you're getting an error like this: Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option.

Then, you can simply add the following in build.gradle (in Groovy) in order to tell kotlin to build using 1.8.

compileKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}
nazmul idris
  • 432
  • 6
  • 17
1

I tried all of the above and I was still getting warnings for compileTestKotlin.
This is what cleared all of them in the root build.gradle:

tasks.withType(org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile).all {
  kotlinOptions {
    jvmTarget = 17
  }
}
Marko Bonaci
  • 5,622
  • 2
  • 34
  • 55