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

IllegalAccessError in Dagger with KSP2.0.0-1.0.22 and KSP2 #1956

Closed
lwasyl opened this issue Jun 6, 2024 · 13 comments
Closed

IllegalAccessError in Dagger with KSP2.0.0-1.0.22 and KSP2 #1956

lwasyl opened this issue Jun 6, 2024 · 13 comments
Assignees

Comments

@lwasyl
Copy link

lwasyl commented Jun 6, 2024

Stacktrace:

Caused by: java.lang.IllegalAccessError: failed to access class com.google.common.base.NullnessCasts from class com.google.common.base.Suppliers$NonSerializableMemoizingSupplier (com.google.common.base.NullnessCasts is in unnamed module of loader java.net.URLClassLoader @28a2ead8; com.google.common.base.Suppliers$NonSerializableMemoizingSupplier is in unnamed module of loader java.net.URLClassLoader @6cdeb8d1)
        at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers.java:189)
        at dagger.internal.codegen.binding.Binding.dependencies(Binding.java:98)
        at dagger.internal.codegen.binding.SourceFiles.generateBindingFieldsForDependencies(SourceFiles.java:97)
        at dagger.internal.codegen.writing.FactoryGenerator.frameworkFields(FactoryGenerator.java:178)
        at dagger.internal.codegen.writing.FactoryGenerator.constructorParams(FactoryGenerator.java:158)
        at dagger.internal.codegen.writing.FactoryGenerator.addConstructorAndFields(FactoryGenerator.java:146)
        at dagger.internal.codegen.writing.FactoryGenerator.factoryBuilder(FactoryGenerator.java:130)
        at dagger.internal.codegen.writing.FactoryGenerator.topLevelTypes(FactoryGenerator.java:113)
        at dagger.internal.codegen.writing.FactoryGenerator.topLevelTypes(FactoryGenerator.java:82)
        at dagger.internal.codegen.base.SourceFileGenerator.generate(SourceFileGenerator.java:70)
        at dagger.internal.codegen.validation.InjectBindingRegistryImpl$BindingsCollection.generateBindings(InjectBindingRegistryImpl.java:106)
        at dagger.internal.codegen.validation.InjectBindingRegistryImpl.generateSourcesForRequiredBindings(InjectBindingRegistryImpl.java:234)
        at dagger.internal.codegen.DelegateComponentProcessor.postRound(DelegateComponentProcessor.java:127)
        at dagger.internal.codegen.KspComponentProcessor.postRound(KspComponentProcessor.java:68)
        at dagger.spi.internal.shaded.androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:63)
        at com.google.devtools.ksp.impl.KotlinSymbolProcessing.execute(KotlinSymbolProcessing.kt:533)
        at com.google.devtools.ksp.impl.KSPLoader$Companion.loadAndRunKSP(KSPLoader.kt:36)
        at com.google.devtools.ksp.impl.KSPLoader.loadAndRunKSP(KSPLoader.kt)

Kotlin 2.0.0 + KSP2.0.0-1.0.22 (ksp.useKSP2=true) + Dagger 2.51.1. Feels related to the other issue with classpath, but if it's an incompatibility that should be fixed on the Dagger side then I'll open an issue there.

@BraisGabin
Copy link

Feels related to the other issue with classpath

For reference, the other issue is this one #1911

@aiyu-ayaan
Copy link

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':core:kspStudentReleaseKotlin'.
> A failure occurred while executing com.google.devtools.ksp.gradle.KspAAWorkerAction
   > failed to access class com.google.common.base.NullnessCasts from class com.google.common.base.Suppliers$NonSerializableMemoizingSupplier (com.google.common.base.NullnessCasts is in unnamed module of loader java.net.URLClassLoader @1da5a084; com.google.common.base.Suppliers$NonSerializableMemoizingSupplier is in unnamed module of loader java.net.URLClassLoader @6a396bab)

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 20s

@ansman
Copy link
Contributor

ansman commented Jul 11, 2024

So I did some digging and I found the issue. The problem happens when you have two KSP tasks in the same Gradle project. The tasks use a custom classloader for each run. But since the classes are loaded into the running VM, you end up in trouble.

So for example, say you have an Android project that has debug and release. You'll then have two separate tasks. The issue can happen like this for example:

  1. Task 1 runs
  • It uses classloader ABC
  • It loads class com.google.common.base.NullnessCasts
  1. Task 2 runs
  • It uses classloader XYZ
  • It loads com.google.common.base.Suppliers$NonSerializableMemoizingSupplier
  • com.google.common.base.Suppliers$NonSerializableMemoizingSupplier tries to access com.google.common.base.NullnessCasts

Now the issue happens because com.google.common.base.NullnessCasts is already loaded, but using a different classloader and since com.google.common.base.NullnessCasts is package private the JVM throws the illegal access error.

I'm not sure what the correct solution is. KSP could perhaps try and force the class loader to be GCed and thus unload the classes.

@ZacSweers
Copy link
Contributor

The best solution here would be for KSP to shade its guava use, as it doesn't need to be a part of the public API anyway I think?

@ansman
Copy link
Contributor

ansman commented Jul 16, 2024

They already do. It's Daggers Guava that conflicts with Rooms guava I believe. But it's worth noting that it can happen with any dependency of course

@ZacSweers
Copy link
Contributor

I'm not sure how that can be the case? I don't see the shading in those package names

@ansman
Copy link
Contributor

ansman commented Jul 16, 2024

@ansman
Copy link
Contributor

ansman commented Jul 16, 2024

I made a special build of KSP that logged the classloaders so I've confirmed that it's not KSP's guava that is causing issues, it's one from a processor

@ZacSweers
Copy link
Contributor

Ahh, dagger should be shading then?

@ansman
Copy link
Contributor

ansman commented Jul 16, 2024

Dagger shading it would be an option, but other libraries can have issues too. Ideally this should be solved on the KSP side I think. If they could unload the CL and thus unload the classes that would be ideal I think. I don't know if there are other ways of isolating the VM that doesn't include forking.

@ZacSweers
Copy link
Contributor

true, and dagger does expose guava in its public APIs in some places so it probably can't shade

@ansman
Copy link
Contributor

ansman commented Jul 24, 2024

The way I solved it was by removing ksp.useKSP2=true from my gradle.properties file. I hope this helps you.

That’s not solving it, that is disabling KSP2 thus circumventing the issue

@ting-yuan
Copy link
Collaborator

This is likely caused by the conflict between the bundled Guava in KSP and the one pulled as the dependency of Dagger. The KSP artifact is going to be changed from symbol-processing-aa to symbol-processing-aa-embeddable in 1.0.24. The latter renames all bundled dependencies to avoid conflicts.

Please reopen if KSP 1.0.24 doesn't work for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants