Unable to Generate Jetpack Compose Previews
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)
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.
Thank you for the report. I'm investigating it.
Fixed at 2.6.1 If the problem continues to reproduce please reopen it.
Thank you for your support with this change! Can confirm we have this working in our application again 🙌