Status Update
Comments
am...@google.com <am...@google.com>
am...@google.com <am...@google.com> #2
I'm using the latest Android Studio (H) and I can see the root cause being displayed (" Kotlin reflection implementation is not found at runtime. Make sure you have kotlin-reflect.jar in the classpath")
I can see you were using Flamingo by the time of the report. Can you please confirm you observe the same behavior in newer Android Studio versions? Thanks!
el...@airbnb.com <el...@airbnb.com> #3
I just tried on Hedgehog canary 7 using the repro project I attached above (I just changed AGP to 8.2.0-alpha07) and I still have the same experience.
The IDE preview fails, with a message saying "There was problem to load the PreviewParameterProvider defined. Please double-check its constructor and the values property implementation. The IDE logs should contain the full exception stack trace." (Screenshot attached)
If I check the logs there is nothing about kotlin reflection missing, all I see is the stacktrace below.
Additionally, the kotlin reflect library definitely is included as an implementation dependency of this module in my repro project, so it should not be missing regardless. It looks like in the screenshot you shared you are not using my exact repro project?
com.example.composepreviewbugrepro.DataPreviewParameterProvider.$FailToLoadPreviewParameterProvider
java.lang.NoSuchMethodException: com.example.composepreviewbugrepro.DataPreviewParameterProvider.$FailToLoadPreviewParameterProvider
at androidx.compose.ui.tooling.ComposableInvoker.findComposableMethod(ComposableInvoker.kt:83)
at androidx.compose.ui.tooling.ComposableInvoker.invokeComposable(ComposableInvoker.kt:190)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1$composable$1.invoke(ComposeViewAdapter.kt:711)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1$composable$1.invoke(ComposeViewAdapter.kt:709)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1.invoke(ComposeViewAdapter.kt:746)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1.invoke(ComposeViewAdapter.kt:704)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
gm...@google.com <gm...@google.com>
M....@cmcmarkets.com <M....@cmcmarkets.com> #4
I resolved the same stack trace in my PreviewParameterProvider by preventing it from trying to translate @StringRes resources
Go through your object graph until you're sure that your preview doesn't try to use any Android Context
Clean architecture should avoid the problem but it's easy to create a bug when the UX is complicated enough and the team developing it gets big enough
se...@garmin.com <se...@garmin.com> #5
Another reflection issue, probably adjacent (ignore if it's off topic). This code:
class MyClass {
var m1 = 1
var m2 = 2
}
@Preview()
@Composable
fun PropertyEditorPreview() {
var instance = remember {
MyClass()
}
Surface {
Column {
instance::class.members.forEach {
if (it is KProperty1<*, *>) {
Text("${it.getter.call(instance)})
}
}
}
}
}
Yields this exception:
java.lang.IllegalAccessException: class _layoutlib_._internal_.kotlin.reflect.jvm.internal.calls.CallerImpl$FieldGetter cannot access a member of class MyClass with modifiers "private"
at jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
at java.lang.reflect.Field.checkAccess(Field.java:1102)
at java.lang.reflect.Field.get(Field.java:423)
at _layoutlib_._internal_.kotlin.reflect.jvm.internal.calls.CallerImpl$FieldGetter.call(CallerImpl.kt:161)
at _layoutlib_._internal_.kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:107)
...
el...@airbnb.com <el...@airbnb.com> #6
Is there any update on this bug? It has been many months and this is preventing my company from using Compose previews for a core part of our workflow with our internal framework.
am...@google.com <am...@google.com> #7
Thanks for following up. Unfortunately, our team is extremely busy and our backlog for this quarter is full. I'll make sure to add this and the other PreviewParameter
related issues for our Q2 backlog. As there is no promise that these issues will be fixed, they'll certainly be looked at and investigated. Thanks!
jo...@tmediatech.com <jo...@tmediatech.com> #8
se...@wlcm.tech <se...@wlcm.tech> #9
Hi,
Is there any progress on this?
My lib,
am...@google.com <am...@google.com> #10
Hi. No progress yet, but we're planning to at least start an investigation this quarter. We'll keep you posted.
di...@google.com <di...@google.com>
di...@google.com <di...@google.com>
an...@google.com <an...@google.com> #11
Thank you for your patience while our engineering team worked to resolve this issue. A fix for this issue is now available in:
- Android Studio Meerkat | 2024.3.1 Canary 3
- Android Gradle Plugin 8.9.0-alpha03
We encourage you to try the latest update.
If you notice further issues or have questions, please file a new bug report.
Thank you for taking the time to submit feedback — we really appreciate it!
Description
compose-bom = "2022.10.00"
Android Studio Build:
Flamingo 2022.2.1
Kotlin version:
1.7.20
Steps to Reproduce or Code Sample to Reproduce:
I am using Kotlin reflect within my preview parameter object class; specifically I call "isData" internally for the purposes of some tooling we use. This call incorrectly returns false during the Preview runtime, which leads to an exception. It works correctly if the preview is deployed to the device.
The downstream issue is that the root crash is completely obscured. The IDE refers me to the logs, but the logs only show a `NoSuchMethodException: com.example.composepreviewbugrepro.DataPreviewParameterProvider.$FailToLoadPreviewParameterProvider` error. This makes it hard to find the root cause
A repro sample is attached, but the code is simply this:
@Composable
fun Greeting(data: MyData) {
Text(text = data.str,)
}
// This preview this will fail with ""Expected a data class""
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
ComposePreviewBugReproTheme {
Greeting(MyData("hi"))
}
}
// This fails to preview: "There was problem to load the PreviewParameterProvider defined."
// the IDE logs however don't show the root issue: ""Expected a data class"
@Preview(showBackground = true)
@Composable
fun GreetingPreview_Parameterized(
@PreviewParameter(DataPreviewParameterProvider::class) data: MyData
) {
ComposePreviewBugReproTheme {
Greeting(MyData("hi"))
}
}
class DataPreviewParameterProvider : PreviewParameterProvider<MyData> {
override val values = sequenceOf(
MyData("1"),
MyData("2"),
MyData("3"),
)
}
data class MyData(val str: String) {
init {
check(this::class.isData) {
"Expected a data class"
}
}
}