Room cannot find implementation

假如想象 提交于 2019-11-27 05:51:04

问题


I have a problem with testing a Room database: when I run the test, I get this exception:

java.lang.RuntimeException: cannot find implementation for database.TicketDatabase. TicketDatabase_Impl does not exist
at android.arch.persistence.room.Room.getGeneratedImplementation(Room.java:92)
at android.arch.persistence.room.RoomDatabase$Builder.build(RoomDatabase.java:454)
at com.sw.ing.gestionescontrini.DatabaseTest.setDatabase(DatabaseTest.java:36)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1886)

Class DatabaseTest:

public class DatabaseTest {

    TicketDatabase database;
    DAO ticketDAO;


    @Before
    public void setDatabase() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Context context = InstrumentationRegistry.getTargetContext();
        database = Room.inMemoryDatabaseBuilder(context, TicketDatabase.class).build();

        Method method = TicketDatabase.class.getDeclaredMethod("ticketDao()");
        method.setAccessible(true);
        ticketDAO = (DAO) method.invoke(database, null);
    }
}

gradle file:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'
    defaultConfig {
        applicationId "com.sw.ing.gestionescontrini"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    defaultConfig {
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'

    annotationProcessor 'android.arch.lifecycle:compiler:1.0.0'
    compile 'android.arch.persistence.room:rxjava2:1.0.0-rc1'
    testCompile'android.arch.persistence.room:testing:1.0.0-rc1'

}

I don't really know what this implementation should be, I searched for a solution but all I found doesn't work for me. For instance, many found a solution adding kapt "android.arch.persistence.room..." but gradle doesn't recognize "kapt".


回答1:


kapt is for Kotlin.

First, add:

annotationProcessor "android.arch.persistence.room:compiler:1.0.0"

to your dependencies closure.

Then, upgrade android.arch.persistence.room:rxjava2 and android.arch.persistence.room:testing to 1.0.0 instead of 1.0.0-rc1.

ref: https://developer.android.com/jetpack/androidx/releases/room




回答2:


for Kotlin change the 'annotationProcessor' keyword to 'kapt' in gradle file.

kapt "android.arch.persistence.room:compiler:1.1.1"

and also add on top of the dependency file

apply plugin: 'kotlin-kapt'

ref: https://developer.android.com/jetpack/androidx/releases/room




回答3:


If You Use Kotlin sure exists this code in your in grade file.

apply plugin: "kotlin-kapt"

// Room
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"

Documentation: https://developer.android.com/jetpack/androidx/releases/room




回答4:


I see some people around here (Vishu Bhardwaj and others on similar StackOverflow questions) complains the accepted answer does not work for them. I think it deserve mentioning I had a similar problem in a MULTI modules project that needed a trick around the accepted answer.

In my multi modules project the room database dependencies where included mostly in one basic module and exported using proper api notation but room code was split along 2 different modules. Project compiled with no warning but java.lang.RuntimeException: cannot find implementation for database... was raised on run-time.

This was fixed by adding

annotationProcessor "android.arch.persistence.room:compiler:$room_version"

in ALL modules that included Room related code.




回答5:


This gradle works nicely. Notice the plugin kotlin-kapt at the beggining. It's crucial.

apply plugin: 'kotlin-kapt'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "????"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    implementation 'android.arch.persistence.room:runtime:1.1.1'
    kapt 'android.arch.persistence.room:compiler:1.1.1'
}



回答6:


I did as everybody said in above answer still no luck.
The issue on my end was that, I was doing insertion on main thread.

roomDatabase = Room.databaseBuilder(DexApplication.getInstance(),MyRoomDatabase.class,"db_name")
                    .fallbackToDestructiveMigration() // this is only for testing, 
                       //migration will be added for release
                    .allowMainThreadQueries() // this solved the issue but remember that its For testing purpose only
                    .build();

Explanation:

.allowMainThreadQueries() 

allows you run queries on the main thread. But keep in mind to remove it and implement, RxJava, Live Data or any other background process mechanism for querying database. Hope that would help.




回答7:


Add below plugin and dependency

apply plugin: 'kotlin-kapt'

kapt "android.arch.persistence.room:compiler:1.1.1"




回答8:


I will add complete answer that solved my problem

First add all the room dependency of android x second add apply plugin: 'kotlin-kapt' and replace annotationProcessor of room compiler with kept



来源:https://stackoverflow.com/questions/47274677/room-cannot-find-implementation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!