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

Layoutlib Bridge initialization failed #489

Closed
theomota opened this issue Jul 6, 2022 · 22 comments
Closed

Layoutlib Bridge initialization failed #489

theomota opened this issue Jul 6, 2022 · 22 comments
Labels
waiting on user Waiting on information from OP

Comments

@theomota
Copy link

theomota commented Jul 6, 2022

Description
I was not able to use the Paparazzi in my projects. I'm always getting the same error, it seems like Paparazzi is crashing during the rendering of my Composables. I've tried different types of combinations changing CompileSDK and lib version, but I'm always getting the same error.

Steps to Reproduce

Using compose version 1.1.1 and testing a simple button.

class PaparazziLinkButtonTest {
    @get:Rule
    val paparazzi = Paparazzi()

    @Test
    fun TestingSnap() {
        paparazzi.snapshot(name = "simpleLinkButton") {
            LinkButton(
                text = "Testing Paparazzi",
                onClick = {}
            )
        }
    }
}

It fails when I try to run the test with the message SEVERE: broken: Layoutlib Bridge initialization failed

Additional information:

  • Paparazzi Version: 1.0.0
  • OS: OS: MacOS 12.4.0
  • Compile SDK: 31
  • Gradle Version: 7.3.3
  • Android Gradle Plugin Version: 7.2.1
  • Compose version: 1.1.1

Log

Jul 06, 2022 4:00:48 PM app.cash.paparazzi.internal.PaparazziLogger error
SEVERE: broken: Layoutlib Bridge initialization failed
com.android.layoutlib.common.util.ReflectionUtils$ReflectionException: java.lang.reflect.InvocationTargetException
	at com.android.layoutlib.common.util.ReflectionUtils.invoke(ReflectionUtils.java:84)
	at com.android.layoutlib.common.util.ReflectionUtils.invokeStatic(ReflectionUtils.java:92)
	at com.android.layoutlib.bridge.Bridge.init(Bridge.java:239)
	at app.cash.paparazzi.internal.Renderer.prepare(Renderer.kt:84)
	at app.cash.paparazzi.Paparazzi.prepare(Paparazzi.kt:158)
	at app.cash.paparazzi.Paparazzi$apply$statement$1.evaluate(Paparazzi.kt:122)
	at app.cash.paparazzi.agent.AgentTestRule$apply$1.evaluate(AgentTestRule.kt:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.android.layoutlib.common.util.ReflectionUtils.invoke(ReflectionUtils.java:80)
	... 41 more
Caused by: java.lang.NoSuchMethodError: 'java.lang.String android.text.TextUtils.join(java.lang.CharSequence, java.lang.Object[])'
	at android.graphics.fonts.FontVariationAxis.toFontVariationSettings(FontVariationAxis.java:190)
	at android.graphics.FontListParser.readFont(FontListParser.java:269)
	at android.graphics.FontListParser.readFamily(FontListParser.java:191)
	at android.graphics.FontListParser.readFamilies(FontListParser.java:143)
	at android.graphics.FontListParser.parse(FontListParser.java:118)
	at android.graphics.fonts.SystemFonts.getSystemFontConfigInternal_Original(SystemFonts.java:244)
	at android.graphics.fonts.SystemFonts_Delegate.getSystemFontConfigInternal(SystemFonts_Delegate.java:65)
	at android.graphics.fonts.SystemFonts.getSystemFontConfigInternal(SystemFonts.java:244)
	at android.graphics.fonts.SystemFonts.getSystemPreinstalledFontConfig(SystemFonts.java:230)
	at android.graphics.Typeface.deferredStaticInitializer(Typeface.java:1395)
	... 46 more


Failed to init Bridge.
java.lang.IllegalStateException: Failed to init Bridge.
	at app.cash.paparazzi.internal.Renderer.prepare(Renderer.kt:83)
	at app.cash.paparazzi.Paparazzi.prepare(Paparazzi.kt:158)
	at app.cash.paparazzi.Paparazzi$apply$statement$1.evaluate(Paparazzi.kt:122)
	at app.cash.paparazzi.agent.AgentTestRule$apply$1.evaluate(AgentTestRule.kt:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)


@theomota
Copy link
Author

theomota commented Jul 6, 2022

I was able to make it work by isolating the paparazzi tests in a new module. Is that required?

@AdamMc331
Copy link

@theomota Can you clarify what you meant about a new module? I just created an Android library module, added paparazzi to it, and I'm seeing this exact same issue.

@theomota
Copy link
Author

theomota commented Jul 7, 2022

@AdamMc331 Sure, let me try to explain what happened step-by-step.

  • In the project that I'm currently working on we have a module (android lib) with Composables. In this module, we have regular Snapshot tests for every component (by regular I mean androidTest).
  • I tried to add paparazzi in this module with the intent to migrate all our screenshot tests to paparazzi. I tried everything with no luck.... Always the same error Layoutlib Bridge initialization failed.
  • After that, I create a new module (Snapshot-tests) and added the Paparazzi plugin to it.. and it worked. I have no idea why, It has the same versions as the old module and it also has the old module as a dependency. So I can really explain why it works.

I hope that helps

@AdamMc331
Copy link

Hmm okay. I will give this a try, too!

@AdamMc331
Copy link

@theomota Any chance you can share the build.gradle file of your snapshots-tests module? What does the compose config look like within that module?

@theomota
Copy link
Author

theomota commented Jul 7, 2022

Sure, but it's a pretty regular gradle file.

plugins {
    id 'com.android.library'
    id 'org.jetbrains.kotlin.android'
    id 'app.cash.paparazzi'
}

android {
    compileSdk 31

    defaultConfig {
        minSdk 27
        targetSdk 31

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion versions.composeCompiler
    }
}

dependencies {
    implementation project(":ComposeLib")
    testImplementation 'junit:junit:4.13.2'
}

@AdamMc331
Copy link

Hmm, well I was still getting the same issue after all. I guess we'll see if one of the maintainers can weigh in in a bit. I'll try to make a reproducible repo that has less fluff.

@AdamMc331
Copy link

Well, this whole plan backfired. I created a brand new project, and the android-components module of this project was able to run the recordPaparazziDebug task without any issues.

https://github.com/AdamMc331/PaparazziComposeSample

I guess I'll try to do some comparisons to see if I can figure out what makes this project different from my other one.

@AdamMc331
Copy link

Yep I'm stumped, it's not a minimal reproducible project but here is my setup: AdamMc331/TOA#146

@theomota
Copy link
Author

theomota commented Jul 7, 2022

@AdamMc331 You should also try the 1.1.0-SNAPSHOT version.

@AdamMc331
Copy link

Same issue. :(

@luis-cortes
Copy link
Collaborator

@theomota Can you provide a minimal reproduction sample? Is your project also KMM?

@AdamMc331 I tried to open your project in AS, but was unable to get it to sync. That said, running from the command line yields a different stack trace than what's posted above.

@AdamMc331
Copy link

Hmm, I wonder if KMM is the issue, though if it's specifically within an Android lib module I'm not sure why that would be the case.

@theomota
Copy link
Author

Sorry, I was not able to create a reproduction sample.
I'll try again during the weekend.

@handstandsam
Copy link

I'm seeing the Failed to init Bridge issue as well after bumping compileSdk 32 -> 33 globally. When I set the compileSdk back to 32 for this specific module, it fixes it. Unfortunately I can't share this code as a repro case.

@jrodbx
Copy link
Collaborator

jrodbx commented Jul 26, 2022

I'm seeing the Failed to init Bridge issue as well after bumping compileSdk 32 -> 33 globally. When I set the compileSdk back to 32 for this specific module, it fixes it. Unfortunately I can't share this code as a repro case.

Paparazzi (read: layoutlib) doesn't support compileSdk 33 at the moment.

Hmm, I wonder if KMM is the issue, though if it's specifically within an Android lib module I'm not sure why that would be the case.

This would be a helpful scenario to confirm/eliminate. Can you try and relay your results?

@jrodbx
Copy link
Collaborator

jrodbx commented Jul 26, 2022

For the compileSdk 32 issue, you can backport Paparazzi to use earlier platform versions in snapshot tests, like so:

    environment = detectEnvironment().copy(
      platformDir = "${androidHome()}/platforms/android-32",
      compileSdkVersion = 32
    ),

@jrodbx
Copy link
Collaborator

jrodbx commented Jul 29, 2022

@theomota any luck on obtaining a sample repro?

@jrodbx jrodbx added the waiting on user Waiting on information from OP label Aug 1, 2022
@jrodbx
Copy link
Collaborator

jrodbx commented Aug 8, 2022

Closing due to lack of activity. Please re-file with sample repro.

@rharter
Copy link

rharter commented Aug 30, 2022

For the compileSdk 32 issue, you can backport Paparazzi to use earlier platform versions in snapshot tests, like so:

    environment = detectEnvironment().copy(
      platformDir = "${androidHome()}/platforms/android-32",
      compileSdkVersion = 32
    ),

Any reason this can't be part of the upstream detectEnvironment()? i.e. use the latest supported platform if the detected one is greater than it?

@BMeloCarvalho
Copy link

Paparazzi (read: layoutlib) doesn't support compileSdk 33 at the moment.

Is there any idea if this support will be released soon?

@XabierGoros
Copy link

In my case I was getting the same error no matter the version of the Paparazzi library I was using. My first quick thought was it had something to do with the Apple Silicon architecture like some other cases with other libraries, however it hasn't.

Since I successfully achieved to run the sample project provided here. I just tried to find the 7 differences between this project and my personal one. After simplifying it to the maximum, it turns out that applying the JetBrains Kover gradle plugin for code coverage caused the Bridge error. Commenting out that plugin, everything worked as expected (applying the compileSdkVersion workaround in the environment since I use target 33). I don't exactly know how the plugin affects to the Bridge, however, at least from my experience it seems some gradle plugins may be part of the cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting on user Waiting on information from OP
Projects
None yet
Development

No branches or pull requests

8 participants