dokka
dokka copied to clipboard
AssertionError: Recursion detected in a lazy value under LockBasedStorageManager in multiplatform project
Describe the bug
./gradle dokkaGfm fails on a multiplatform project with the following exception: java.lang.AssertionError: Recursion detected in a lazy value under LockBasedStorageManager@61bed5ef (Dokka).
Repository with an example project: https://github.com/illarionov/playground-android-composite-build/tree/dokka-typealias-recursion (dokka-typealias-recursion branch).
This project has a shared Jvm + Android source set and some typealias defined.
To Reproduce
Clone the above example repository, or create a new multiplatform project with about the following submodule configuration (build.gradle.kts):
plugins {
id("org.jetbrains.kotlin.multiplatform")
id("com.android.library")
}
kotlin {
androidTarget()
jvm()
applyDefaultHierarchyTemplate()
sourceSets {
val jvmAndAndroid by creating {
dependsOn(commonMain.get())
}
androidMain.get().dependsOn(jvmAndAndroid)
jvmMain.get().dependsOn(jvmAndAndroid)
}
}
Create a Kotlin source code file in the shared source set (composeApp/src/jvmAndAndroid/kotlin/org/example/dokka/Types.jvmAndAndroid.kt):
package org.example.dokka
import java.io.File
typealias File = File
Run ./gradlew dokkaGfm --stacktrace. It will fail with the following stacktrace:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':composeApp:dokkaGfm'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:130)
at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:282)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:128)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:116)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:331)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:318)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:314)
at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:314)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
Caused by: java.lang.AssertionError: Recursion detected in a lazy value under LockBasedStorageManager@61bed5ef (Dokka)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor.getDefaultType(LazyTypeAliasDescriptor.kt:57)
at org.jetbrains.kotlin.types.KotlinTypeFactory.simpleType(KotlinTypeFactory.kt:85)
at org.jetbrains.kotlin.types.KotlinTypeFactory.simpleType$default(KotlinTypeFactory.kt:77)
at org.jetbrains.kotlin.resolve.TypeResolver.resolveTypeForTypeAlias(TypeResolver.kt:727)
at org.jetbrains.kotlin.resolve.TypeResolver.resolveTypeForClassifier(TypeResolver.kt:583)
at org.jetbrains.kotlin.resolve.TypeResolver$resolveTypeElement$1.visitUserType(TypeResolver.kt:278)
at org.jetbrains.kotlin.psi.KtVisitorVoid.visitUserType(KtVisitorVoid.java:937)
at org.jetbrains.kotlin.psi.KtVisitorVoid.visitUserType(KtVisitorVoid.java:21)
at org.jetbrains.kotlin.psi.KtUserType.accept(KtUserType.java:42)
at org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:49)
at org.jetbrains.kotlin.resolve.TypeResolver.resolveTypeElement(TypeResolver.kt:257)
at org.jetbrains.kotlin.resolve.TypeResolver.resolvePossiblyBareType(TypeResolver.kt:136)
at org.jetbrains.kotlin.resolve.TypeResolver.resolveType(TypeResolver.kt:126)
at org.jetbrains.kotlin.resolve.TypeResolver.resolveAbbreviatedType(TypeResolver.kt:104)
at org.jetbrains.kotlin.resolve.DescriptorResolver.lambda$resolveTypeAliasDescriptor$2(DescriptorResolver.java:788)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor.getUnderlyingType(LazyTypeAliasDescriptor.kt:54)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor.computeClassDescriptor(LazyTypeAliasDescriptor.kt:74)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor.access$computeClassDescriptor(LazyTypeAliasDescriptor.kt:34)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor$initialize$2.invoke(LazyTypeAliasDescriptor.kt:70)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor$initialize$2.invoke(LazyTypeAliasDescriptor.kt:70)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor.getClassDescriptor(LazyTypeAliasDescriptor.kt:56)
at org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor.computeDefaultType(AbstractTypeAliasDescriptor.kt:98)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor.access$computeDefaultType(LazyTypeAliasDescriptor.kt:34)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor$initialize$1.invoke(LazyTypeAliasDescriptor.kt:69)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor$initialize$1.invoke(LazyTypeAliasDescriptor.kt:69)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor.getDefaultType(LazyTypeAliasDescriptor.kt:57)
at org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator.DokkaDescriptorVisitor$visitTypeAliasDescriptor$2$1.invokeSuspend(DefaultDescriptorToDocumentableTranslator.kt:844)
at org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator.DokkaDescriptorVisitor$visitTypeAliasDescriptor$2$1.invoke(DefaultDescriptorToDocumentableTranslator.kt)
at org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator.DokkaDescriptorVisitor$visitTypeAliasDescriptor$2$1.invoke(DefaultDescriptorToDocumentableTranslator.kt)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:78)
at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:264)
at org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator.DokkaDescriptorVisitor.visitTypeAliasDescriptor(DefaultDescriptorToDocumentableTranslator.kt:842)
at org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator.DokkaDescriptorVisitor.access$visitTypeAliasDescriptor(DefaultDescriptorToDocumentableTranslator.kt:161)
at org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator.DokkaDescriptorVisitor$visitTypealiases$2$invokeSuspend$$inlined$parallelMap$1$1.invokeSuspend(parallelCollectionOperations.kt:28)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
Workaround: if we replace the typealias line to typealias File = java.io.File, then the build will succeed.
Installation
- Operating system: Linux
- Build tool: Gradle v8.7
- Dokka version: 1.9.20
- Kotlin version: 1.9.23
Related issues: https://github.com/Kotlin/dokka/issues/3317 https://github.com/Kotlin/dokka/issues/3513
Thank you for the reproducer.
The problem is that the Dokka Gradle Plugin wrongly(?) defines jvmAndAndroid as a common platform here.
That means that:
import java.io.File
typealias File = File
java.io.File is unresolved since JDK is only available for a JVM platform.
In K1, it causes a recursion (AssertionError that fails a Dokka run).
In K2, it just leads to an unresolved type.
An intermediate solution: do not fail the build to at least let the users build documentation, even if the reference is lost.
Overall, to address the issue properly, we need to investigate how this case should be handled, what the expected behaviour is from Kotlin's perspective, whether such setups are even allowed.