99

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

pgSystemTester
  • 8,979
  • 2
  • 23
  • 49
Federico Taschin
  • 2,027
  • 3
  • 15
  • 28
  • 1
    I am having the same issue. The accepted answer does not work for me. Please help if you found a solution. Below is dependency : compile 'android.arch.persistence.room:runtime:1.1.0' annotationProcessor 'android.arch.persistence.room:compiler:1.1.0' compile 'android.arch.persistence.room:rxjava2:1.1.0' – Vishu Bhardwaj Jun 14 '18 at 08:41
  • 1
    @VishuBhardwaj Check you have an annotation for the Database above the database class like this: `@Database(entities = {Entities.class}, version = 1, exportSchema = true)` – nicklocicero Jul 06 '18 at 04:25

17 Answers17

102

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

lasec0203
  • 2,422
  • 1
  • 21
  • 36
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
53

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

lasec0203
  • 2,422
  • 1
  • 21
  • 36
Manzur Alahi
  • 1,870
  • 23
  • 19
50

java.lang.RuntimeException: cannot find implementation for com.example.kermovie.data.repository.local.MoviesDatabase. MoviesDatabase_Impl does not exist

You have to add the following code to your build.gradle:

apply plugin: 'kotlin-kapt' 

dependencies {
    def room_version = '2.3.0'
    implementation 'androidx.room:room-runtime:$room_version'
    implementation "androidx.room:room-ktx:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
}

You may have to change room_version variable when a newer version is available.

You can check for a newer version on the following web mvnrepository.com

Iker Solozabal
  • 1,232
  • 11
  • 16
30

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

atymic
  • 3,093
  • 1
  • 13
  • 26
Hossein Hajizadeh
  • 1,357
  • 19
  • 10
9

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.

Grigore Madalin
  • 1,195
  • 11
  • 15
6

Add this in your app module's buld.gradle file

    //The Room persistence library provides an abstraction layer over SQLite
    def room_version = "2.3.0"
    implementation("androidx.room:room-runtime:$room_version")
    annotationProcessor "androidx.room:room-compiler:$room_version"

In your data access object file add the follwoing annotation

@Database(entities = [EntityClassName::class], version = 1)

Replace entity class name and database version code as per your project need.

If you are using kotlin, apply kapt plugin to the annotation processor as following line:

apply plugin: 'kotlin-kapt'

Then Replace annotationProcessor "androidx.room:room-compiler:$room_version" with the following line:

kapt "androidx.room:room-compiler:$room_version"
Razz
  • 452
  • 6
  • 9
  • 1
    If you are using Data Binding: – Razz Jun 04 '21 at 08:06
  • 1
    Works for me. My build.gradle(:app) plugins: id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'kotlin-kapt' dependencies: implementation "androidx.room:room-ktx:2.4.0-rc01" kapt "androidx.room:room-compiler:2.4.0-rc01" – dobhareach Feb 04 '22 at 10:14
4

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'
}
Ráfagan
  • 2,165
  • 2
  • 15
  • 22
3

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.

Wajid
  • 2,235
  • 1
  • 19
  • 29
  • You did this `.fallbackToDestructiveMigration() // this is only for testing` but forgot to `.allowMainThreadQueries() // this also is only for testing.` Never allow main thread queries on production applications. – Naveen Niraula Feb 03 '19 at 10:25
  • @NaveenNiraula edited the answer, thanks for suggestion. – Wajid Feb 04 '19 at 10:11
3

Add below plugin and dependency

apply plugin: 'kotlin-kapt'

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

3

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

Dharman
  • 30,962
  • 25
  • 85
  • 135
blackHawk
  • 6,047
  • 13
  • 57
  • 100
3

I had the same problem. This happens when you forget to add the compiler dependency.

Add these dependencies

    def room = "2.3.0"
    implementation "androidx.room:room-runtime:$room"
    implementation "androidx.room:room-ktx:$room"
    kapt "androidx.room:room-compiler:$room"

2

I'm coming a little bit late but I had the same issue but none of the answers helped me. So I hope my experience will help others. Room couldn't find the implementation while executing my instrumentation tests so adding below line to my gradle file fixed the problem

kaptAndroidTest "androidx.room:room-compiler:$room_version"

If you use annotation processors for your androidTest or test sources, the respective kapt configurations are named kaptAndroidTest and kaptTest

Marc Calandro
  • 226
  • 2
  • 6
2

In my case, adding the following annotation above the database class solves the problem.

@Database(entities = {Entities.class}, version = 1, exportSchema = false)
public abstract class TheDatabase extends RoomDatabase {...}

Thanks to @nicklocicero.

KikiYu
  • 3,087
  • 1
  • 13
  • 14
1

it means your room runtime dependency is missing .. please add below dependency in your build.gradle(module) file. This will resolve your issue :)

 dependencies{

     def room_version = "2.2.6"
        implementation "androidx.room:room-ktx:$room_version"
        implementation "androidx.room:room-runtime:$room_version"
        kapt "androidx.room:room-compiler:$room_version"  
}
Jayant Kumar
  • 775
  • 5
  • 12
1

I was using KSP and it turned out that the KSP and kotlin versions are incompatible with each other. I upgraded the ksp plugin version to 1.8.21-1.0.11 and it fixed my problem.

in the project-level gradle:

plugins {
    id 'com.google.devtools.ksp' version '1.8.21-1.0.11' apply false
}

In the app level gradle:

plugins {
    id 'com.google.devtools.ksp'
}

You might have to update jvm to 17 as well.

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = '17'
    }

There is a related issue on the KSP repo as well https://github.com/google/ksp/issues/1347

asim mehmood
  • 121
  • 10
0

In my case, I was doing a complete rewrite alongside old code and put the new code in a temporary package called new without thinking it might conflict with the Java keyword. Evidently the Room compiler just ignores packages with that name without giving warnings. Android Studio doesn't warn when creating a new package, but it does say "not a valid package name" when entered in the rename dialog even though it still allows renaming to that. I renamed the package to redesign and no longer had the issue.

Pilot_51
  • 7,337
  • 3
  • 29
  • 26
0

add this

@Database(entities = [Entity::class], version = 1) to your db class

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 01 '22 at 02:17