Preventing the use of JDK 7/8 APIs when targeting JVM 1.6

I’m using Kotlin to build an application that’s distributed to users with older JVM versions, while still using modern language features (I don’t want to be stuck on Java 6).

By targeting JVM 1.6, I’m able to run the application on older JVMs. However, the only way I can make sure I also don’t use later JDK APIs, e.g. Path, java.time, etc. is by doing the compilation on JDK 1.6. Otherwise, the compilation succeeds, and then causes a runtime exception only when run on older JVMs due to missing classes.

Here’s a minimal build.gradle:

plugins {
    id "org.jetbrains.kotlin.jvm" version "1.2.41"
}

repositories { jcenter() }

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib"
}

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

When compiling using JDK 1.8, I can successfully compile:

import java.time.Instant

fun main(args: Array<String>) {
    println(Instant.now())
}

For this use case, am I supposed to run Gradle and therefore compile the Kotlin files using JDK 1.6?

You need JDK 1.8 (at least) to run the Kotlin compiler, however you can specify the path to JDK from which APIs are being resolved. You can do it with the jdkHome property in kotlinOptions:

    kotlinOptions {
        jvmTarget = "1.6"
        jdkHome = "path_to_jdk_1.6"
    }

Thanks! I understand now that the jdkHome property doesn’t affect what JDK is being used to run the Kotlin compiler, just which JDK is being used for the resolved APIs. That makes perfect sense!