-
Notifications
You must be signed in to change notification settings - Fork 275
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
KSP2: KtInvalidLifetimeOwnerAccessException: Access to invalid KtAlwaysAccessibleLifetimeToken: PSI has changed since creation #1854
Comments
The keys of androidx.room.compiler.processing.ksp.KspArrayType.Factory.reverseBuiltinArrayLookup are stale. It could be a bug in Room. |
Is the Room team aware of this? Didn't find it in the public tracker. |
I'm running into the same issue with my processor and another processor. What I'm doing is caching a
To me this seems to be a regression in KSP 2. I tested with I'm running into this issue with another processor that defers processing of symbols to later rounds and caches these symbols. When it's actually processing the symbols the same exception is thrown:
The kotlin-inject processor caches the deferred classes here.
|
Using elements across rounds is currently unsupported, because generated code may affect the elements. For example, the return type of a function may be an error in round 1 and defined by a class generated in round 2. In KSP1, caching elements across rounds happens to work for some cases but not all. In KSP2, the lifecycle check is more strict and the error is always thrown. This is not a regression. KSP's deferral mechanism (returning symbols to be deferred from process()) is designed to handle this use case. Please try to use it and let us know if it doesn't serve your use case well. |
I'm not sure I understand this sentence. The kotlin-inject processor supports multiple rounds and defers generating files when needed. This creates challenges though. To avoid generating duplicate files, you either must track which were already generated when getting symbols with an annotation, or you get symbols of with the annotation only of the new files of this round. kotlin-inject does the latter and therefore must track the deferred symbols. Even the previous options requires tracking symbols from the previous round. An alternative is to try generating duplicate files and catch the exception, but that doesn't sound right. I feel like I'm missing something or there's a gap. My processor is in a similar situation. My workaround for now looks something like this, which only works because I can "reload" or "refresh" the class symbol: deferredClassesFromPreviousRound.forEach {
val clazz = resolver.getClassDeclarationByName(it.qualifiedName!!)!!
generate...(resolver, clazz)
} But all of this feels wrong. |
`InjectProcessor` remembers deferred symbols across rounds. KSP (KSP 2 in particular) forbids to cache symbols across rounds and verifies the lifecycle. The fix is trying to get new symbols of the deferred classes each round. For more details: google/ksp#1854
Fyi I had asked about this originally when implementing and I told that what I was doing was ok https://kotlinlang.slack.com/archives/C013BA8EQSE/p1635106134012300 |
My last comment in that thread still stands
You have to track what you deferred yourself between rounds as you won't get those symbols given back to you which makes it very easy to trip on this issue. |
The deferral mechanism is designed around
There are no other ways to access deferred symbols though, so it makes more sense to defer the root elements than others, or at least those with annotation. We should probably have created another API that allows access to all deferred symbols. Before doing that, I'd like to know what you think. Is the current API fit your use case? |
From my own testing, the API isn't reliable. In our internal project I see non-deferred symbols from previous rounds popping up again. So I thought this was by design until I checked the documentation yesterday. Any chance this changed recently? I'm not sure if I can isolate the problem, it definitely happens in unit tests. |
Would you mind checking if the popped up symbols were (indirectly) from |
Oh that's good to know, I was using |
Even if I switched I'd think I'd still want to get the deferred symbols directly so I can report errors on the final round in |
Reusing symbols between rounds is not supported and throws an error on ksp2. Unfortunately this means we need to use `getSymbolsWithAnnotation` instead of our custom functions as they are currently the only way to access updated deferred symbols. We still keep a list of the symbol names so that we can run a final processing pass on the last round. See google/ksp#1854
Reusing symbols between rounds is not supported and throws an error on ksp2. Unfortunately this means we need to use `getSymbolsWithAnnotation` instead of our custom functions as they are currently the only way to access updated deferred symbols. We still keep a list of the symbol names so that we can run a final processing pass on the last round. See google/ksp#1854
Reusing symbols between rounds is not supported and throws an error on ksp2. Unfortunately this means we need to use `getSymbolsWithAnnotation` instead of our custom functions as they are currently the only way to access updated deferred symbols. We still keep a list of the symbol names so that we can run a final processing pass on the last round. See google/ksp#1854
Just pushed up https://github.com/evant/kotlin-inject/pull/393/files to fix this. Should show off the trade-offs that are needed with the current api using |
No, I'm definitely using fun getSymbolsWithAnnotation(annotationName: String, inDepth: Boolean = false): Sequence<KSAnnotated> And because of this issue I have to do this: fun Resolver.getNewSymbolsWithAnnotation(annotation: KClass<*>): Sequence<KSAnnotated> {
val newFiles = getNewFiles().toSet()
return getSymbolsWithAnnotation(annotation)
.filter { it.containingFile in newFiles }
} |
@vRallev won't the code you posted filter out the deferred symbols again? Since they may not be from new files for the round. |
Yes, currently we track deferred symbols in our processor like you do. |
Don't reuse symbols between rounds Reusing symbols between rounds is not supported and throws an error on ksp2. Unfortunately this means we need to use `getSymbolsWithAnnotation` instead of our custom functions as they are currently the only way to access updated deferred symbols. We still keep a list of the symbol names so that we can run a final processing pass on the last round. See google/ksp#1854
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [me.tatarka.inject:kotlin-inject-runtime](https://togithub.com/evant/kotlin-inject) | `0.6.3` -> `0.7.1` | [![age](https://developer.mend.io/api/mc/badges/age/maven/me.tatarka.inject:kotlin-inject-runtime/0.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/me.tatarka.inject:kotlin-inject-runtime/0.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/me.tatarka.inject:kotlin-inject-runtime/0.6.3/0.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/me.tatarka.inject:kotlin-inject-runtime/0.6.3/0.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [me.tatarka.inject:kotlin-inject-compiler-ksp](https://togithub.com/evant/kotlin-inject) | `0.6.3` -> `0.7.1` | [![age](https://developer.mend.io/api/mc/badges/age/maven/me.tatarka.inject:kotlin-inject-compiler-ksp/0.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/me.tatarka.inject:kotlin-inject-compiler-ksp/0.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/me.tatarka.inject:kotlin-inject-compiler-ksp/0.6.3/0.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/me.tatarka.inject:kotlin-inject-compiler-ksp/0.6.3/0.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>evant/kotlin-inject (me.tatarka.inject:kotlin-inject-runtime)</summary> ### [`v0.7.1`](https://togithub.com/evant/kotlin-inject/blob/HEAD/CHANGELOG.md#071-2024-06-12) ##### Fixed - Removed erroneous `@KmpComponentCreator` annotation. ### [`v0.7.0`](https://togithub.com/evant/kotlin-inject/blob/HEAD/CHANGELOG.md#070-2024-06-12) ##### Changed - `@Scope` annotations now take arguments into account. This means for example, if you have ```kotlin @​Scope annotation class NamedScope(val value: String) ``` then the scope: `@NamedScope("one")` and `@NamedScope("two")` would be treated as distinct. Previously they were treated as the same scope. - Legacy implicit assisted injection (not using the `@Assisted` annotation) is now an error. - The build will now fail if multiple qualifiers are applied in the same place, instead of picking the first one. This applies both to the new annotation (see below) and `javax.inject.Qualifier`. A minor exception is you are allowed to have one of each type to aid in migration. In that case the `me.tatarka.inject` one will be chosen. ##### Added - Added a `me.tatarka.inject.annotations.Qualifier` annotation as an alternative to using typealias. For example, you could do: ```kotlin @​Qualifier annotation class Named(val value: String) @​Inject class MyClass(@​Named("one") val one: String, @​Named("two") val two: String) @​Component abstract class MyComponent { abstract val myClass: MyClass @​Provides @​Named("one") fun provideOne(): String = "one" @​Provides @​Named("two") fun provideTwo(): String = "two" } ``` This behaves the same as `javax.inject.Qualifier` does when you have `me.tatarka.inject.enableJavaxAnnotations=true`. - Added a new `@KmpComponentCreate` annotation for nicer multiplatform support. This allows you to create component instances from common code when generating platform-specific outputs. ```kotlin // src/commonMain @​Component abstract class MyKmpComponent @​KmpComponentCreate expect fun createKmp(): MyKmpComponent ``` see the new [multiplatform docs](docs/multiplatform.md) for more details. - You can now use an `@Inject` annotation on an inner class provided the outer class can be provided. ```kotlin @​Inject class Outer { @​Inject inner class Inner } @​Component abstract class MyComponent { abstract val inner: Outer.Inner } ``` ##### Removed - The KAPT backend is removed, please migrate to KSP if you haven't already. ##### Fixed - Fixed cases of invalid code generation ([#​321](https://togithub.com/evant/kotlin-inject/issues/321), [#​337](https://togithub.com/evant/kotlin-inject/issues/337), [#​313](https://togithub.com/evant/kotlin-inject/issues/313)). - Fixed an exception thrown on KSP2 when running multiple rounds ([google/ksp#1854](https://togithub.com/google/ksp/issues/1854)). - Fixed various issues with handling method overrides in components ([#​309](https://togithub.com/evant/kotlin-inject/issues/309), [#​375](https://togithub.com/evant/kotlin-inject/issues/375)) - Allow scope annotations on both an interface and component implementation if they are the same scope ([#​320](https://togithub.com/evant/kotlin-inject/issues/320)). </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/julioromano/mooviez). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zOTMuMCIsInVwZGF0ZWRJblZlciI6IjM3LjM5My4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Added `rank` ordering Added tests for `@ContributesBinding` Fixed google/ksp#1854
Added `rank` ordering Added tests for `@ContributesBinding` Fixed google/ksp#1854
Added `rank` ordering Added tests for `@ContributesBinding` Fixed google/ksp#1854
FYI I'm facing this as well when trying to run Koin with KSP2. I'm not 100% sure whether it's the same issue, because the stacktrace is slightly different:
|
I'm facing this issue when using the latest version of Glide or Room with
|
I can reliably reproduce the error when building an Android standalone test module when both test and application modules use Room or Glide KSP processor. |
Also seeing this reproduce 100% of the time in our project since updating to 1.0.26 and testing KSP2 |
More importantly, I am also seeing this coming from KSP itself. No custom processors are in the stacktrace
|
This is also a project that worked with KSP2 in 1.0.25 |
See https://youtrack.jetbrains.com/issue/KT-67158 for test cases.
The text was updated successfully, but these errors were encountered: