I thought that using `org.gradle.toolchains.foojay...
# gradle
j
I thought that using
org.gradle.toolchains.foojay-resolver-convention
combined with toolchain setup will make it work automatically. (i.e. will use proper JDK without manual reconfiguration of default JDK/IntelliJ) I want the build: • use JDK 21 to build • want Java 11 jvmTarget to be produced • currently, to test, JDK 18 is the default in the system/in Android Studio. Setup:
Copy code
extensions.getByType<JavaPluginExtension>().apply {
		toolchain {
			languageVersion.set(JavaLanguageVersion.of(21))
		}
	}
	tasks.withType<KotlinCompile>().configureEach {
		compilerOptions {
			jvmTarget.set(JvmTarget.JVM_11)
		}
	}
	commonExtension.compileOptions {
		sourceCompatibility = JavaVersion.VERSION_11
		targetCompatibility = JavaVersion.VERSION_11
		isCoreLibraryDesugaringEnabled = true
	}
The build produces this error for hilt task:
Copy code
Compilation failed; see the compiler output below.
  error: cannot access module-info
    bad class file: /modules/java.base/module-info.class
      class file has wrong version 65.0, should be 62.0
Any idea what Im doing wrong?
v
Can you show a build
--scan
URL with the error, or at lest a full
--stacktrace
if not?
Something expects a
module-info.class
of
java.base
to be from Java 18 while it is from Java 21
j
Untitled
This is the exception.
It seems, if I use the new feature in Gradle 8.13 to configure the deamon it works. So, is this my misunderstanding how this works? • Do I have to explicitly change Android Studio's the JDK anyway? Until supported by 2025.1? • Or the deamon support is required? • Or I do something else wrong?
v
Hm, sounds like this might be a Gradle bug that you should report. If you run
./gradlew :app:hiltJavaCompileDevHsiDebug --debug
you should have in the output
NormalizingJavaCompiler
logging the
Compiler arguments
, what does that log line look like?
Besides that we now know your question is off-topic here, as it is not Kotlin related. 😄
j
Initially, https://youtrack.jetbrains.com/issue/KTIJ-24311/task-current-target-is-17-and-kaptGenera[…]ask-current-target-is-1.8-jvm-target-compatibility-should seemed quite related and hitl using kapt seems like the source of culprits. If you say so, thx, I don't see what/where the issue is 😄
v
Well, it is the Java Compiler that is failing, but could of course be the KGP misconfiguring it, yeah. 🤷‍♂️ What did that log line look like?
j
There is a single line:
Copy code
2025-02-28T12:24:33.266+0100 [DEBUG] [org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler] Compiler arguments: -source 11 -target 11
v
That's all? o_O I think there should be more arguments. Also maybe share a few lines around.
j
Oh yeah, there is ton of them 😄
From the end:
Copy code
/Users/hrach/storage/__redacted__/lr/app/build/tmp/kotlin-classes/devHsiDebug:/Users/hrach/storage/__redacted__/lr/app/build/tmp/kapt3/classes/devHsiDebug:/Users/hrach/storage/__redacted__/lr/app/build/intermediates/javac/devHsiDebug/compileDevHsiDebugJavaWithJavac/classes -XDstringConcat=inline -parameters -Adagger.fastInit=enabled -Adagger.hilt.internal.useAggregatingRootProcessor=false -Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true -Adagger.fastInit=enabled -Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true -Adagger.hilt.android.internal.projectType=APP -Adagger.hilt.internal.useAggregatingRootProcessor=false --system /Users/hrach/.gradle/caches/8.13/transforms/0f023d2f24aaa91a6672c9a6b20b530c/transformed/output/jdkImage /Users/hrach/storage/__redacted__/lr/app/build/generated/hilt/component_trees/devHsiDebug/dagger/hilt/internal/processedrootsentinel/codegen/_com___redacted___App.java /Users/hrach/storage/__redacted__/lr/app/build/generated/hilt/component_trees/devHsiDebug/com/__redacted__/App_ComponentTreeDeps.java
I see stuff from app module, also the kapt3 path.
v
Can you not show the full?
Hm, I guess
/Users/hrach/.gradle/caches/8.13/transforms/0f023d2f24aaa91a6672c9a6b20b530c/transformed/output/jdkImage
contains a Java 18 JDK and something does not like that. Not sure where this is coming from, maybe some Android-specific thing, Android is always a bit special. 😄
j
The
release
file there contains
Copy code
JAVA_VERSION="21"
MODULES="java.base"
Is that inline with that?
v
Ah, yes, confused numbers. 65 = 21 62 = 18 So it expects 18 but found 21. The question is, why does it even expect 18 if you configured the toolchain to be 21. What is the log line before where it tells which toolchain is used for the compiler? And did you also configure 18 anywhere for anything?
j
Oh you're right, the lines before that:
Copy code
2025-02-28T12:24:33.257+0100 [DEBUG] [org.gradle.cache.internal.DefaultCacheCoordinator] Creating new cache for jarAnalysis, path /Users/hrach/.gradle/caches/8.13/javaCompile/jarAnalysis.bin, access org.gradle.cache.internal.DefaultCacheCoordinator@1cfc1cc4
2025-02-28T12:24:33.257+0100 [DEBUG] [org.gradle.cache.internal.DefaultInMemoryCacheDecoratorFactory] Creating in-memory store for cache /Users/hrach/.gradle/caches/8.13/javaCompile/jarAnalysis.bin (max size: 103800)
2025-02-28T12:24:33.257+0100 [DEBUG] [org.gradle.cache.internal.LockOnDemandCrossProcessCacheAccess] Acquiring file lock for Java compile cache (/Users/hrach/.gradle/caches/8.13/javaCompile)
2025-02-28T12:24:33.257+0100 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire exclusive lock on Java compile cache (/Users/hrach/.gradle/caches/8.13/javaCompile).
2025-02-28T12:24:33.257+0100 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired on Java compile cache (/Users/hrach/.gradle/caches/8.13/javaCompile).
2025-02-28T12:24:33.258+0100 [DEBUG] [org.gradle.cache.internal.DefaultCacheCoordinator] Creating new cache for classAnalysis, path /Users/hrach/.gradle/caches/8.13/javaCompile/classAnalysis.bin, access org.gradle.cache.internal.DefaultCacheCoordinator@1cfc1cc4
2025-02-28T12:24:33.258+0100 [DEBUG] [org.gradle.cache.internal.DefaultInMemoryCacheDecoratorFactory] Creating in-memory store for cache /Users/hrach/.gradle/caches/8.13/javaCompile/classAnalysis.bin (max size: 2076800)
2025-02-28T12:24:33.261+0100 [INFO] [org.gradle.api.internal.tasks.compile.incremental.SelectiveCompiler] Full recompilation is required because no incremental change information is available. This is usually caused by clean builds or changing compiler arguments.
2025-02-28T12:24:33.262+0100 [INFO] [org.gradle.jvm.toolchain.internal.DefaultToolchainJavaCompiler] Compiling with toolchain '/Users/hrach/Library/Java/JavaVirtualMachines/azul-18.0.2.1/Contents/Home'.
But no 18 anywhere, just the default JDK in the AndroidStudio/JAVA_HOME.
v
I guess not it becomes really complicated to investigate further. 😄 You probably have to debug the Gradle code to find out where the toolchain of the Java compilation task is set to a Java 18 toolchain which often is quite a PITA from my experience. If you are lucky, you might be able to just break in the compile task action and evaluate the toolchain property, but most often it is not too clear where it is coming form. 😕
Ah wait, this is not the "normal" java compile task, but something some plugin added.
hiltJavaCompileDevHsiDebug
The configured toolchain is not automatically used by all Java compile tasks registered by arbitrary plugins iirc.
So probably the plugin adding that task does not configure the toolchain that is configured in the Java extension
j
Awesome, this is something I understand what I'm looking for 🙂
Thank you!
v
Copy code
val hiltJavaCompileDevHsiDebug by tasks.existing(JavaCompile::class) {
    javaCompiler = javaToolchains.compilerFor(the<JavaPluginExtension>().toolchain)
}
And maybe report to the according plugin to do that eventually
Btw. if you do not have type-safe accessors,
extensions.getByType<JavaPluginExtension>().apply {
is better written as
configure<JavaPluginExtension> {
. Works the same but is nicer to read and write.
❤️ 1
And here the issue about making all
JavaCompile
tasks use the configured toolchain by default: https://github.com/gradle/gradle/issues/16791
Ah, no that is about
JavaExec
, but probably in the same vein
👍 1
j
OK, this fixed the build for me:
Copy code
afterEvaluate {
    val hiltJavaCompileDevHsiDebug by tasks.existing(JavaCompile::class) {
        javaCompiler = javaToolchains.compilerFor(java.toolchain)
    }
}
Thank you very much!
v
Don't ever use
afterEvaluate
! If the task is only registered later, use a lazy construct like
Copy code
tasks.withType<JavaCompile>().named { it == "hiltJavaCompileDevHsiDebug" }.configureEach {
    javaCompiler = javaToolchains.compilerFor(java.toolchain)
}
j
yeah, it was just quickfix to try out 😄 Thank you for pointing out the correct final solution!
👌 1