48

I'm new to Android development and I'm currently building my first real app. I'm trying to implement a MVVM architecture and because of that I'm having a viewModel for each fragment and each viewModel has a viewModelFactory. At least, this is how I understood it has to be.

I use the boilerplate code everyone seems to use for the factory:

class ExampleViewModelFactory(private val exampleDao: ExampleDao) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(exampleViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return ExampleViewModel(exampleDao) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

Now the problem is, that the compiler is giving me the following error:

e: C:\Users\ ...\ExampleViewModel.kt: (64, 7): Inheritance from an interface with '@JvmDefault' members is only allowed with -Xjvm-default option

And this error is produced by the viewModelFactory class I have implemented in the viewModel. I really can't tell what this means and I cant find anything helpful or even related to my specific problem. I basically followed some basic tutorials about creating your first app, but I keep on running into errors like this. In most cases, I was able to fix the problem by myself, but this time it's different.

I know that a lot of you have a lot of experience and knowledge, so I hope that some of you find the time to help me and give me a hint what I can do to fix this.

Edric
  • 24,639
  • 13
  • 81
  • 91
FuManchuObey
  • 483
  • 1
  • 3
  • 6

7 Answers7

62

It seems like you are either directly or indirectly (through some other library) depending on Lifecycle 2.5.0-alpha01.

As per this issue:

You need to temporarily add following to your build.gradle:

tasks.withType(KotlinCompile).configureEach {
    kotlinOptions {
        freeCompilerArgs += [
                "-Xjvm-default=all",
        ]
    }
}

Note that in certain circumstances you may want to use all-compatibility instead of all, learn more about that in Jebrain's blogpost.

Starting with kotlin 1.6.20 you won't need touch build.gradle for more information see KT-47000

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • Thank you very much for your fast and helpfull answer. I'll take a look into the blogpost you've provided. – FuManchuObey Feb 04 '22 at 21:31
  • Thanks a lot. I was looking for this answer since last 3 days. – Chirag Savsani Feb 07 '22 at 11:40
  • 14
    If you use `KotlinComplie` and got error you can use `org.jetbrains.kotlin.gradle.tasks.KotlinCompile` – Chirag Savsani Feb 07 '22 at 11:42
  • you save my life , but should the question is "Inheritance from an interface with '@JvmDefault' members is only allowed with -Xjvm-default option" just remove the error message i cant resolve" for better on people searching, i able found when go to make question only not on goolge. and put the text on body/question. – Yogi Arif Widodo Feb 20 '22 at 04:53
  • 4
    in which build.gradle should i add this? – Shoaib Kakal Feb 20 '22 at 06:52
  • 1
    @ShoaibKhalid module's build.gradle – theapache64 Mar 08 '22 at 19:27
  • Where inside of `build.gradle` did you add this code? I've tried multiple options such as appending to the end of the file, within `android`, etc. but I still receive an error. I have also tried @ChiragSavsani solution. – John Harrington Mar 16 '22 at 22:21
  • 2
    @TedLavender instead onf `tasks.withType(KotlinCompile).configureEach {` Use `tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {` – Chirag Savsani Mar 17 '22 at 11:35
  • 1
    Would it be really bad practice to extend ViewModelProvider.NewInstanceFactory instead of implementing ViewModelProvider.Factory ? – user2857033 Aug 28 '22 at 06:41
  • ViewModelProvider.NewInstanceFactory can be used as well instead of ViewModelProvider.Factory – prashant Mar 22 '23 at 06:11
21

Update; If you use 1.6.20 version of Kotlin, then changing build.gradle is NOT required.

Old answer:

Try putting these line inside of android{} block in module build.gradle file

 kotlinOptions{
    freeCompilerArgs += [
            "-Xjvm-default=all",
    ]
}

If above code doesn't work try adding these below lines inside dependencies{} block

    tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach{
    kotlinOptions{
        freeCompilerArgs +=["-Xjvm-default=all",]
    }
}
Top-Master
  • 7,611
  • 5
  • 39
  • 71
Vivek Gupta
  • 747
  • 4
  • 13
8

Kotlin version (kts) of @ianhanniballake's answer

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class).configureEach {
    kotlinOptions {
        freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
    }
}
theapache64
  • 10,926
  • 9
  • 65
  • 108
  • 1
    Should either of these statements be added to the end of `build.gradle` or is there a specific section of the file ie `android` or `dependencies` that it should be placed within? I receive an error when adding the code and syncing: `org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method withType() for arguments` – John Harrington Mar 16 '22 at 17:33
1

Use the stable version, in this case 2.4.1. I have the same problem and I solved it by making this change.

https://developer.android.com/jetpack/androidx/releases/lifecycle

FGCDEV
  • 19
  • 2
1

In my case the problem was in kotlin libraries version

I was using in build.gradle:

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10

and in build.gradle (app) [for Java compatibility]:

implementation "org.jetbrains.kotlin:kotlin-stdlib:1.6.10"

then I create a common kotlin_version variable in ext:

buildscript {
  ext {
    ...
    kotlin_version='1.7.10'
  } ...

and use for both (each in respective place):

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
Wesley Campagna
  • 131
  • 1
  • 3
0

use theses dependencies in your gradle

implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
0

When you override the create fun of ViewModelProvider.Factory avoid the question mark after vieModel

Incorrect:

<T : ViewModel?>

Correct:

< T : ViewModel>

Seems like there where some changes in the class.

Boken
  • 4,825
  • 10
  • 32
  • 42