Status Update
Comments
el...@google.com <el...@google.com>
ap...@google.com <ap...@google.com> #2
For Kotlin 2.0 and KSP 2.0 the Cannot change attributes of configuration ':composeApp:debugFrameworkIosX64' after it has been locked for mutation
really seems like a KSP issue. You should file a bug in their repository with a sample app if possible.
If you downgrade to Kotlin 1.9 then things 'should' work, there are example apps out there with such configuration, like the following one:
ap...@google.com <ap...@google.com> #3
Will try to use the example provided by you to check if it fixes the issue.
za...@gmail.com <za...@gmail.com> #4
Note that this issue happens when applying the Compose, KSP and Room Plugin together in Kotlin 2.0.x, the workaround for now is to not use the Room Gradle Plugin and instead specify the schema location vis KSP arguments:
// In the build.gradle
ksp {
arg("room.schemaLocation", "${projectDir}/schemas")
}
el...@google.com <el...@google.com> #5
Hi, I encountered a similar problem and was able to resolve it by updating the dependencies
room = "2.7.0-alpha08"
ksp = "2.0.20-1.0.25"
compose-plugin = "1.6.11"
kotlin = "2.0.20"
ap...@google.com <ap...@google.com> #6
Branch: androidx-main
commit 19309786e1e720aebb977d0e73f21017156ae67d
Author: Daniel Santiago Rivera <danysantiago@google.com>
Date: Thu Jul 04 10:51:06 2024
Update Room initialization strategy for KMP
Changes Room reflection replacement strategy for KMP to one where Room generates an 'actual' implementations of an 'expect object' that is linked via an @AssociatedObjectKey annotated annotation in the @Database definition, that ultimately allows the builder; at runtime, to find the object, cast it to a known interface and invoke the generated override function that instantiates the generated database implementation.
Bug: 316978491
Bug: 338446862
Bug: 342905180
Test: ./gradlew :room:integration-tests:room-testapp-multiplatform:allTests
Relnote: """Changes the instantiation setup for a RoomDatabase in a KMP project.
Due to Kotlin 2.0 compilation model, the strategy of referencing a to-be-generated function, named 'instantiateImpl()' is longer viable. Two new APIs, @ConstructedBy and RoomDatabaseConstructor are introduced that replace the 'instantiateImpl()' strategy. The new strategy is as follow:
1. Define an expect object that implements RoomDatabaseConstructor
```
expect object MyDatabaseCtor : RoomDatabaseConstructor<MyDatabase>
```
2. Link the object with the @Database declaration using @ConstructedBy
```
@Database(...)
@ConstructedBy(MyDatabaseCtor::class) // NEW
abstract class MyDatabase : RoomDatabase
```
3. Create a new database instance but without passing a factory argument
```
fun createNewDatabase(path: String) =
Room.databaseBuilder<AppDatabase>(name = path)
.setDriver(BundledSQLiteDriver())
.setQueryCoroutineContext(Dispatchers.IO)
.build()
```
"""
Change-Id: Ic787a5c84f318dea0e004cd35efb2202bc6902dc
M room/integration-tests/multiplatformtestapp/build.gradle
M room/integration-tests/multiplatformtestapp/src/androidInstrumentedTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BuilderTest.kt
M room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseAutoMigrationTest.kt
M room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseMigrationTest.kt
M room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BaseTypeConverterTest.kt
M room/integration-tests/multiplatformtestapp/src/commonTest/kotlin/androidx/room/integration/multiplatformtestapp/test/SampleDatabase.kt
M room/integration-tests/multiplatformtestapp/src/jvmTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BuilderTest.kt
M room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/AutoMigrationTest.kt
M room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/BuilderTest.kt
M room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/InvalidationTest.kt
M room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/MigrationTest.kt
M room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/QueryTest.kt
M room/integration-tests/multiplatformtestapp/src/nativeTest/kotlin/androidx/room/integration/multiplatformtestapp/test/TypeConverterTest.kt
M room/room-common/api/current.txt
M room/room-common/api/restricted_current.txt
M room/room-common/bcv/native/current.txt
M room/room-common/build.gradle
A room/room-common/src/commonMain/kotlin/androidx/room/ConstructedBy.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Database.kt
A room/room-common/src/jvmMain/kotlin/androidx/room/ConstructedBy.jvm.kt
A room/room-common/src/nativeMain/kotlin/androidx/room/ConstructedBy.native.kt
M room/room-compiler/src/main/kotlin/androidx/room/DatabaseProcessingStep.kt
M room/room-compiler/src/main/kotlin/androidx/room/ext/xpoet_ext.kt
M room/room-compiler/src/main/kotlin/androidx/room/processor/Context.kt
M room/room-compiler/src/main/kotlin/androidx/room/processor/DatabaseProcessor.kt
M room/room-compiler/src/main/kotlin/androidx/room/processor/ProcessorErrors.kt
M room/room-compiler/src/main/kotlin/androidx/room/vo/Database.kt
A room/room-compiler/src/main/kotlin/androidx/room/writer/DatabaseObjectConstructorWriter.kt
D room/room-compiler/src/main/kotlin/androidx/room/writer/InstantiateImplWriter.kt
A room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseConstructorProcessorTest.kt
M room/room-compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
M room/room-compiler/src/test/kotlin/androidx/room/vo/DatabaseTest.kt
M room/room-compiler/src/test/kotlin/androidx/room/writer/DatabaseObjectConstructorWriterKotlinCodeGenTest.kt
A room/room-compiler/src/test/test-data/kotlinCodeGen/actualDatabaseConstructor.kt
D room/room-compiler/src/test/test-data/kotlinCodeGen/instantiateImpl_simple.kt
M room/room-gradle-plugin/src/test/test-data/multiplatform-project/src/commonMain/kotlin/room/testapp/CommonDatabase.kt
M room/room-gradle-plugin/src/test/test-data/multiplatform-project/src/jvmMain/kotlin/room/testapp/MyDatabase.kt
M room/room-gradle-plugin/src/test/test-data/multiplatform-project/src/nativeMain/kotlin/room/testapp/MyDatabase.kt
M room/room-runtime/api/current.txt
M room/room-runtime/api/restricted_current.txt
M room/room-runtime/bcv/native/current.txt
M room/room-runtime/src/androidMain/kotlin/androidx/room/Room.android.kt
A room/room-runtime/src/commonMain/kotlin/androidx/room/RoomDatabaseConstructor.kt
M room/room-runtime/src/jvmMain/kotlin/androidx/room/Room.jvm.kt
M room/room-runtime/src/nativeMain/kotlin/androidx/room/Room.native.kt
M room/room-runtime/src/nativeMain/kotlin/androidx/room/util/KClassUtil.native.kt
M room/room-testing/bcv/native/current.txt
M room/room-testing/src/nativeMain/kotlin/androidx/room/testing/MigrationTestHelper.native.kt
pr...@google.com <pr...@google.com> #7
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.room:room-common:2.7.0-alpha06
androidx.room:room-common-iosarm64:2.7.0-alpha06
androidx.room:room-common-iossimulatorarm64:2.7.0-alpha06
androidx.room:room-common-iosx64:2.7.0-alpha06
androidx.room:room-common-jvm:2.7.0-alpha06
androidx.room:room-common-linuxx64:2.7.0-alpha06
androidx.room:room-common-macosarm64:2.7.0-alpha06
androidx.room:room-common-macosx64:2.7.0-alpha06
androidx.room:room-compiler:2.7.0-alpha06
androidx.room:room-gradle-plugin:2.7.0-alpha06
androidx.room:room-runtime:2.7.0-alpha06
androidx.room:room-runtime-android:2.7.0-alpha06
androidx.room:room-runtime-iosarm64:2.7.0-alpha06
androidx.room:room-runtime-iossimulatorarm64:2.7.0-alpha06
androidx.room:room-runtime-iosx64:2.7.0-alpha06
androidx.room:room-runtime-jvm:2.7.0-alpha06
androidx.room:room-runtime-linuxx64:2.7.0-alpha06
androidx.room:room-runtime-macosarm64:2.7.0-alpha06
androidx.room:room-runtime-macosx64:2.7.0-alpha06
androidx.room:room-testing:2.7.0-alpha06
androidx.room:room-testing-android:2.7.0-alpha06
androidx.room:room-testing-iosarm64:2.7.0-alpha06
androidx.room:room-testing-iossimulatorarm64:2.7.0-alpha06
androidx.room:room-testing-iosx64:2.7.0-alpha06
androidx.room:room-testing-jvm:2.7.0-alpha06
androidx.room:room-testing-linuxx64:2.7.0-alpha06
androidx.room:room-testing-macosarm64:2.7.0-alpha06
androidx.room:room-testing-macosx64:2.7.0-alpha06
mi...@mercurydevelopment.com <mi...@mercurydevelopment.com> #8
Is there a way now to use non-reflection initialization in a non-kmp project?
Since 2.7.0-alpha06 we don't have instantiateImpl anymore and can't use expect/actual in a non-kmp project to declare a subclass of RoomDatabaseConstructor.
da...@google.com <da...@google.com> #9
If using Room in a JVM-only or Android-only project then @ConstructedBy
is not required and there is no need to declare a 'expect' RoomDatabaseConstructor
.
If you truly want to avoid reflection, then you can pass a factory
to Room.databaseBuilder()
that instantiates the generated implementation directly, but be warned, the name of the implementation is subject to change and not part of the public API.
Example:
// In a JVM only project
@Database(...)
abstract class SampleDatabase : RoomDatabase() {
// ...
}
fun getBuilder() =
Room.inMemoryDatabaseBuilder<SampleDatabase>(
factory = { SampleDatabase_Impl() }
)
Description
In Android/JVM the RoomDatabase.Builder relies on reflection to instantiate the generated RoomDatabase class of an annotated @Database. For native there is no reflection and thus a no-reflection approach has to be implemented.
See go/room-reflection-replacement