stacktrace-decoroutinator icon indicating copy to clipboard operation
stacktrace-decoroutinator copied to clipboard

Unable to Generate Jetpack Compose Previews

Open jcoona opened this issue 1 month ago • 2 comments

Our repository recently implemented Decoroutinator and I noticed that since then a lot of Jetpack Compose Previews in Android Studio would no longer compile. I went through a git bisect and was able to narrow down the cause to Decoroutinator, and further verified by removing the dependency & the issue no longer occurs.

App Implementation:

stacktraceDecoroutinator {
    artifactTypes = setOf(
        ArtifactTypeDefinition.JAR_TYPE,
        ArtifactTypeDefinition.JVM_CLASS_DIRECTORY,
        ArtifactTypeDefinition.ZIP_TYPE,
        "aar",
        "android-classes-directory",
        "android-classes-jar"
    )
}

Stack Trace 1:

java.lang.ExceptionInInitializerError: Exception java.lang.NoClassDefFoundError: Could not initialize class _layoutlib_._internal_.kotlinx.coroutines.flow.StateFlowImpl [in thread "Layoutlib Render Thread"]
  at _layoutlib_._internal_.kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow(StateFlow.kt:187)
  at androidx.compose.runtime.Recomposer.<clinit>(Recomposer.kt:1486)
  at jdk.internal.misc.Unsafe.ensureClassInitialized0
  at jdk.internal.misc.Unsafe.ensureClassInitialized
  at jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized
  at jdk.internal.reflect.MethodHandleAccessorFactory.newFieldAccessor
  at jdk.internal.reflect.ReflectionFactory.newFieldAccessor
  at java.lang.reflect.Field.acquireFieldAccessor
  at java.lang.reflect.Field.getFieldAccessor
  at java.lang.reflect.Field.get
  at com.android.tools.rendering.compose.RenderTaskPatcher.getRecomposerCompanion(RenderTaskPatcher.kt:32)
  at com.android.tools.rendering.compose.RenderTaskPatcher.enableComposeHotReloadMode(RenderTaskPatcher.kt:52)
  at com.android.tools.rendering.RenderTask.createRenderSession(RenderTask.java:807)
  at com.android.tools.rendering.RenderTask.lambda$inflate$7(RenderTask.java:942)
  at com.android.tools.rendering.RenderExecutor.runAsyncActionWithTimeout$lambda$12(RenderExecutor.kt:217)
  at com.android.tools.rendering.RenderExecutor$PriorityRunnable.run(RenderExecutor.kt:338)
  at java.util.concurrent.ThreadPoolExecutor.runWorker
  at java.util.concurrent.ThreadPoolExecutor$Worker.run
  at java.lang.Thread.run

Stack Trace 2:

java.lang.ExceptionInInitializerError: Exception java.lang.ExceptionInInitializerError [in thread "Layoutlib Render Thread"]
	at dev.reformator.stacktracedecoroutinator.provider.DecoroutinatorProviderApiKt.isDecoroutinatorEnabled(provider-api.kt:45)
	at _layoutlib_._internal_.kotlinx.coroutines.flow.StateFlowImpl.<clinit>(StateFlow.kt)
	at _layoutlib_._internal_.kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow(StateFlow.kt:187)
	at androidx.lifecycle.LifecycleRegistry.<init>(LifecycleRegistry.jvm.kt:105)
	at androidx.lifecycle.LifecycleRegistry.<init>(LifecycleRegistry.jvm.kt)
	at androidx.lifecycle.LifecycleRegistry$Companion.createUnsafe(LifecycleRegistry.jvm.kt:332)
	at androidx.compose.ui.tooling.ComposeViewAdapter$FakeSavedStateRegistryOwner$1.<init>(ComposeViewAdapter.android.kt:626)
	at androidx.compose.ui.tooling.ComposeViewAdapter.<init>(ComposeViewAdapter.android.kt:625)
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(Unknown Source)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source)
	at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
	at com.android.tools.rendering.ViewLoader.createNewInstance(ViewLoader.java:311)
	at com.android.tools.rendering.ViewLoader.loadClass(ViewLoader.java:174)
	at com.android.tools.rendering.ViewLoader.loadView(ViewLoader.java:127)
	at com.android.tools.rendering.LayoutlibCallbackImpl.loadView(LayoutlibCallbackImpl.java:277)
	at com.android.tools.rendering.LayoutlibCallbackExDelegate.loadView(LayoutlibCallbackExDelegate.kt:65)
	at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:427)
	at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:438)
	at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:343)
	at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:850)
	at android.view.LayoutInflater.inflate(LayoutInflater.java:544)
	at android.view.LayoutInflater.inflate(LayoutInflater.java:433)
	at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:355)
	at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:462)
	at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:125)
	at com.android.tools.rendering.RenderTask.createRenderSession(RenderTask.java:794)
	at com.android.tools.rendering.RenderTask.lambda$inflate$7(RenderTask.java:942)
	at com.android.tools.rendering.RenderExecutor.runAsyncActionWithTimeout$lambda$12(RenderExecutor.kt:217)
	at com.android.tools.rendering.RenderExecutor$PriorityRunnable.run(RenderExecutor.kt:338)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)

jcoona avatar Dec 13 '25 05:12 jcoona

Extra note: This isn't from the stacktraceDecoroutinator block in the Gradle file - removing that, the issue persists - just having alias(libs.plugins.decoroutinator) present in the plugin collection causes the issue.

jcoona avatar Dec 15 '25 21:12 jcoona

Thank you for the report. I'm investigating it.

Anamorphosee avatar Dec 15 '25 21:12 Anamorphosee

Fixed at 2.6.1 If the problem continues to reproduce please reopen it.

Anamorphosee avatar Dec 28 '25 20:12 Anamorphosee

Thank you for your support with this change! Can confirm we have this working in our application again 🙌

jcoona avatar Jan 05 '26 18:01 jcoona