Room cannot find implementation

Federico Taschin picture Federico Taschin · Nov 13, 2017 · Viewed 29.4k times · Source

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".

Answer

CommonsWare picture CommonsWare · Nov 13, 2017

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