Anyone here understands the relationship among the...
# android
j
Anyone here understands the relationship among these flags?
Copy code
android {
   compileOptions {
       sourceCompatibility JavaVersion.VERSION_..
       targetCompatibility JavaVersion.VERSION_..
   }
  kotlinOptions {
        jvmTarget = 'X.Y'
    }
}
Copy code
kotlin {
    jvmToolchain {
        languageVersion = JavaLanguageVersion.of(XX)
    }
}
Copy code
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(YY)
    }
}
For instance, my project has minSdk 24 and I would like to compile it using JDK 17 to have better GC while compiling it. If I set
languageVersion = JavaLanguageVersion.of(17)
with
sourceCompatibility
,
targetCompatibility
and
jvmTarget
to Java 1.8, I get an error in kapt generated classes... googling it I found this config
Copy code
kapt {
    javacOptions {
        option("--source", "8")
        option("--target", "8")
    }
}
Now I get this warning:
Copy code
'compileDebugJavaWithJavac' task (current target is 1.8) and 'kaptGenerateStubsDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.
AGP 7.4.1, Kotlin 1.8.10 How to fix that warning ? Can I set my
sourceCompatibility
,
targetCompatibility
and
jvmTarget
to Java 11 or 17 without breaking the app in old android versions?
🧵 1
d
Try this in your
android { }
block:
Copy code
kotlin {
        jvmToolchain(11)
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
and in AS settings for Gradle select 17... (assuming you're using AGP > 8
And gradle > 8
the jvmToolchain seems to allow compiling the actual code to a different version than Gradle is using
And android seems to need 11
j
Shouldn't the toolchain select the JDK used to compile and not decide the compatibility of the byte code generated ?
If so, I should be able to use JDK 17 without any problems
d
The toolchain is what is being used to compile the code, the Android Studio setting sets which jvm to run gradle on.
If you don't include the toolchain, Gradle seems to try to use the jvm it runs on to compile the code too.
j
AFAIK, Gradle 7.6.1 supports JDK 17
d
Try what I posted and it should work... I don't know too much more, I was struggling with this today too... until I did what I posted above.
j
Copy code
'compileDebugJavaWithJavac' task (current target is 11) and 'kaptGenerateStubsDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.
I changed everything that was pointing to 1.8 to 11
I left the
languageVersion = JavaLanguageVersion.of(17)
🤷🏼‍♂️ 1
as I want the compilation to happen in JDK 17
m
I use this for JDK 11 compilation + Java 8+ desugaring support:
Copy code
// use JDK 11 for compilation
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(11))
    }
}

android {
    ...

    compileOptions {
        // Flag to enable support for the new language APIs
        // <https://developer.android.com/studio/write/java8-support#library-desugaring>
        coreLibraryDesugaringEnabled true

        // Android generate JDK 11 classes
        sourceCompatibility = "11"
        targetCompatibility = "11"
    }

    kotlinOptions {
        // Kotlin generate JDK 11 classes
        jvmTarget = "11"
    }
}

dependencies {
    // see versions: <https://developer.android.com/studio/write/java8-support#library-desugaring-versions>
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2'
}
I use Gradle 8.0.2, but this configuration is also supported with latest Gradle 7.x version
j
Setting the toolchain makes the compilation use jdk 11
I would like to compile with jdk 17, but generate java 8/11 bytecode
e
Setting this flags are responsible for the bytecode
I believe the usage of JDK is just depend on the JAVA_HOME
unless you use the toolchain dsl
m
Uf, I recently solve the same issue. After all I found: • gradlew is started with JDK defined in JAVA_HOME • Then any worker/task is started on JDK specified with
java.toolchain.languageVersion
• Android and Java generate code / bytecode by
android.compileOptions.*
configuration • Kotlin generate code / bytecode by
android.kotlin.jvmToolchain
configuration on Kotlin 1.7.20+, see here. By default it use version from
java.toolchain.languageVersion
. I am not sure if it must be in android block, or not, but it works in android block. • Kotlin compiler complains if JDK version for Kotlin and Java is different