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

1.3.1 -> 1.3.2 java.lang.IllegalAccessError: class com.android.resources.ResourceType tried to access method 'java.util.stream.Collector #1231

Closed
wezley98 opened this issue Jan 15, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@wezley98
Copy link

wezley98 commented Jan 15, 2024

Description

java.lang.IllegalAccessError: class com.android.resources.ResourceType tried to access method 'java.util.stream.Collector com.google.common.collect.Sets.toImmutableEnumSet()' (com.android.resources.ResourceType and com.google.common.collect.Sets are in unnamed module of loader 'app')
	at com.android.resources.ResourceType.<clinit>(ResourceType.java:175)
	at app.cash.paparazzi.internal.DynamicResourceIdManager$IdProvider.<init>(DynamicResourceIdManager.kt:14)
	at app.cash.paparazzi.internal.DynamicResourceIdManager.<init>(DynamicResourceIdManager.kt:28)
	at app.cash.paparazzi.internal.PaparazziCallback.<init>(PaparazziCallback.kt:52)
	at app.cash.paparazzi.Paparazzi.prepare(Paparazzi.kt:155)
	at app.cash.paparazzi.Paparazzi$apply$1.evaluate(Paparazzi.kt:142)
	at com.google.testing.junit.testparameterinjector.PluggableTestRunner$ContextMethodRule$1.evaluate(PluggableTestRunner.java:433)
	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:112)
	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:40)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:60)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:52)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	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 jdk.proxy1/jdk.proxy1.$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:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)
	at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
	at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(Unknown Source)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at net.bytebuddy.utility.Invoker$Dispatcher.invoke(Unknown Source)
	at net.bytebuddy.utility.dispatcher.JavaDispatcher$Dispatcher$ForNonStaticMethod.invoke(JavaDispatcher.java:1032)
	at net.bytebuddy.utility.dispatcher.JavaDispatcher$ProxiedInvocationHandler.invoke(JavaDispatcher.java:1162)
	at net.bytebuddy.dynamic.loading.$Proxy38.retransformClasses(Unknown Source)
	at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Strategy$2.apply(ClassReloadingStrategy.java:399)
	at net.bytebuddy.dynamic.loading.ClassReloadingStrategy.load(ClassReloadingStrategy.java:227)
	at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101)
	at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6325)
	at app.cash.paparazzi.agent.InterceptorRegistrar$addMethodInterceptors$1.invoke(InterceptorRegistrar.kt:43)
	at app.cash.paparazzi.agent.InterceptorRegistrar$addMethodInterceptors$1.invoke(InterceptorRegistrar.kt:31)
	at app.cash.paparazzi.agent.InterceptorRegistrar.registerMethodInterceptors(InterceptorRegistrar.kt:48)
	at app.cash.paparazzi.Paparazzi$apply$1.evaluate(Paparazzi.kt:139)
	at com.google.testing.junit.testparameterinjector.PluggableTestRunner$ContextMethodRule$1.evaluate(PluggableTestRunner.java:433)
	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:112)
	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:40)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:60)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:52)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	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 jdk.proxy1/jdk.proxy1.$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:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

Steps to Reproduce
After upgrading from Paparazzi 1.3.1 -> 1.3.2 our snapshots tests crash with the above stack.

Expected behavior
Tests don't crash.

Additional information:

  • Paparazzi Version: 1.3.2
  • OS: MacOS
  • Compile SDK: 34
  • Gradle Version: 8.5
  • Android Gradle Plugin Version: 8.2.1
  • Java:
    openjdk 17.0.7 2023-04-18
    OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
    OpenJDK 64-Bit Server VM (build 17.0.7+0-17.0.7b1000.6-10550314, mixed mode)

We are also using com.google.testparameterinjector v1.14

Example Test

@RunWith(TestParameterInjector::class)
class ButtonComponentSnapshotTest(
    @TestParameter baseDeviceConfig: BaseDeviceConfigSinglePhone,
    @TestParameter(value = ["1.0", "1.5"]) fontScale: Float
) {

    object PreviewProvider : TestParameter.TestParameterValuesProvider {
        override fun provideValues(): List<FloatingButton> = MoreButtonParameterProvider().values.toList()
    }

    @get:Rule
    val paparazzi = Paparazzi(
        maxPercentDifference = 0.0,
        deviceConfig = baseDeviceConfig.deviceConfig.copy(
            fontScale = fontScale
        ),
        renderingMode = SessionParams.RenderingMode.SHRINK
    )

    @Test
    fun testButtonComponent(
        @TestParameter(valuesProvider = ModalComponentSnapshotTest.PreviewProvider::class) modal: ModalContent,
        @TestParameter(valuesProvider = ThemeModePreviewProvider::class) isDarkTheme: Theme
    ) {
        paparazzi.snapshot {
            SkyTheme(isSystemDarkTheme = isDarkTheme.mode) {
                Surface {
                    modal.actions.forEach { action ->
                        ButtonComponent(
                            modifier = Modifier.fillMaxWidth(),
                            action = action!!,
                            onCallAction = {}
                        )
                    }
                }
            }
        }
    }
}

To confirm. 1.3.1 works fine for us, only after upgrading to 1.3.2 do we see this issue.

@wezley98 wezley98 added the bug Something isn't working label Jan 15, 2024
@TWiStErRob
Copy link
Contributor

Can you please try this?

// TODO Remove when https://github.com/google/guava/issues/6567 is fixed.
// See also: https://github.com/google/guava/issues/6801.
dependencies.constraints {
    testImplementation("com.google.guava:guava") {
        attributes {
            attribute(
                TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
                objects.named(TargetJvmEnvironment, TargetJvmEnvironment.STANDARD_JVM)
            )
        }
        because("Paparazzi's layoutlib and sdk-common depend on Guava's -jre published variant." +
            "See https://github.com/cashapp/paparazzi/issues/906.")
    }
}

@jrodbx
Copy link
Collaborator

jrodbx commented Jan 16, 2024

Closing as similar/duplicate of #552 and #906.

There is a slight difference in that in those issues, the version of Guava did have missing method support between -jre and -android artifacts. Since then, in the latest Guava, those methods have been copied over, but with internal access (more detail here). It is my hope that in a future version, those methods will become public and this problem goes away.

Until then, I've added the following workaround/snippet to the change log and 1.3.2 release notes:

subprojects {
  plugins.withId("app.cash.paparazzi") {
    // Defer until afterEvaluate so that testImplementation is created by Android plugin.
    afterEvaluate {
      dependencies.constraints {
        add("testImplementation", "com.google.guava:guava") {
          attributes {
            attribute(
              TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
              objects.named(TargetJvmEnvironment, TargetJvmEnvironment.STANDARD_JVM)
            )
          }
          because("LayoutLib and sdk-common depend on Guava's -jre published variant." +
            "See https://github.com/cashapp/paparazzi/issues/906.")
        }
      }
    }
  }
}

Related issues:

@jrodbx jrodbx closed this as completed Jan 16, 2024
@wezley98
Copy link
Author

@jrodbx Thanks, the snippet provided worked 🎉

kotlin dsl needs a slight tweak here:

from
objects.named(TargetJvmEnvironment, TargetJvmEnvironment.STANDARD_JVM)

to
objects.named(TargetJvmEnvironment::class.java, TargetJvmEnvironment.STANDARD_JVM)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants