Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StackOverflowError in dokkaHtml for a multiplatform project when using actual typealiases #2281

Closed
karelp opened this issue Dec 20, 2021 · 7 comments · Fixed by #2664
Closed
Labels
Milestone

Comments

@karelp
Copy link

karelp commented Dec 20, 2021

Describe the bug
I’m using Dokka 1.6.0 in a Kotlin multiplatform project and it crashes with the following exception:

Execution failed for task ':dokkaHtml'.
> java.lang.StackOverflowError (no error message)

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':dokkaHtml'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:188)
	at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:282)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:186)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:174)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
	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:56)
	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$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:79)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:79)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:402)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:389)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:382)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:368)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:61)
Caused by: java.lang.StackOverflowError
	at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:384)
	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.descriptors.impl.AbstractTypeAliasDescriptor$typeConstructor$1.getSupertypes(AbstractTypeAliasDescriptor.kt:108)
	at org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor$typeConstructor$1.getSupertypes(AbstractTypeAliasDescriptor.kt:108)
	at org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor$typeConstructor$1.getSupertypes(AbstractTypeAliasDescriptor.kt:108)
	at org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor$typeConstructor$1.getSupertypes(AbstractTypeAliasDescriptor.kt:108)
	at org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor$typeConstructor$1.getSupertypes(AbstractTypeAliasDescriptor.kt:108)
	at org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor$typeConstructor$1.getSupertypes(AbstractTypeAliasDescriptor.kt:108)
	at org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor$typeConstructor$1.getSupertypes(AbstractTypeAliasDescriptor.kt:108)
	at org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor$typeConstructor$1.getSupertypes(AbstractTypeAliasDescriptor.kt:108)
	at org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor$typeConstructor$1.getSupertypes(AbstractTypeAliasDescriptor.kt:108)
...

Expected behaviour
No exception is thrown.

To Reproduce
I tracked it down to our expect/actual typealias for WeakReference on iOS:
Common:

public expect class WeakReference<T: Any>(referred: T) {
    public fun get(): T?
}

iOS Implementation:

import kotlin.native.ref.WeakReference

internal actual typealias WeakReference<T> = WeakReference<T>

It seems that Dokka gets confused by the WeakReference<T> = WeakReference<T> part and ends up in infinite recursion. The following workaround fixes the problem:

internal actual typealias WeakReference<T> = kotlin.native.ref.WeakReference<T>

Dokka configuration
Just running ./gradlew dokkaHtml

Installation

  • Operating system: macOS
  • Build tool: Gradle v7.2
  • Dokka version: 1.6.0, also reproduced with current master (1.6.10-SNAPSHOT)

Are you willing to provide a PR?
Possibly - need a hint where to start though.

@karelp karelp added the bug label Dec 20, 2021
@yalishevant yalishevant added this to the Stable milestone Mar 24, 2022
@vmishenev
Copy link
Member

Unfortunately, I can not reproduce this with your configuration.
My sample project is here to test this. It works fine.
Can you provide your sample project to reproduce this?

I suppose you have ambiguous WeakReference<T> in your code despite import kotlin.native.ref.WeakReference.
Have you a warning in IDE for actual typealias WeakReference<T> = WeakReference<T>?

@karelp
Copy link
Author

karelp commented May 21, 2022

I tried your version and it is indeed not happening there. However, I still get the same problem in our project even with the newest Dokka version. I’ll investigate further and try to reproduce it within a smaller project.

@anthony-novikov
Copy link

anthony-novikov commented Sep 8, 2022

I have exactly the same issue and same as in the original post it was with WeakReference type aliases.

  • Operating system: masOS 12.5.1
  • Gradle 7.4.2
  • Dokka 1.6.12
  • Kotlin 1.7.0

The suggested workaround to use a fully qualified name instead of using imports works like a charm. The other workaround that came to my mind is to use import aliases

import kotlin.native.ref.WeakReference as NativeWeakReference

actual typealias WeakReference<T> = NativeWeakReference<T>

Import aliases mitigate the ambiguity in a pretty much same way as fully qualified names though may look a bit nicer.

@vmishenev
Copy link
Member

@anthony-novikov Can you provide your sample project to reproduce this?

@anthony-novikov
Copy link

@vmishenev I experienced this issue on one of our internal projects that I can't share, but I'll try to extract the minimal configuration to a demo project and if it's still reproducible I'll share it to you tomorrow.

@anthony-novikov
Copy link

It appears extracting the code to a demo app didn't take that much time as I initially thought, so here it is: https://github.com/anthony-novikov/dokka-weak-ref-demo. Hopefully this will help.

@vmishenev
Copy link
Member

Thank you for the reproducer. It helped to detect a problem.

The fix will be in Dokka 1.7.20.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants