Search code examples
androidkotlingradlebuild.gradle

How can I add latest stable dependencies and plugins to my latest version of Android Studio Koala?


I want to implement MVVM architecture in my project. My Android Studio is Koala. I want to use the latest versions which are compatible with my project.

My module level gradle file looks like this:

plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.jetbrains.kotlin.android)
//    alias(libs.plugins.devtools.ksp)
    alias(libs.plugins.com.google.dagger)

}

android {
    namespace = "com.example.todolist"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.todolist"
        minSdk = 26
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary = true
        }
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.1"
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
}

dependencies {
    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    implementation(libs.androidx.lifecycle.viewmodel.compose)
    implementation(libs.androidx.navigation.compose)
    implementation(libs.dagger.hilt.android)
    implementation(libs.dagger.hilt.android.compiler)
    implementation(libs.androidx.room.compiler)
    implementation(libs.androidx.room.runtime)
    implementation(libs.androidx.hilt.lifecycle.viewmodel)
    implementation(libs.androidx.hilt.compiler)
    implementation(libs.androidx.hilt.navigation.compose)
    implementation(libs.androidx.room.ktx)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
}

My project level gradle file looks like this:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.jetbrains.kotlin.android) apply false
//    alias(libs.plugins.android.library) apply false
}

My version catalog (libs.versions.toml) looks like this:

[versions]
agp = "8.5.1"
kotlin = "1.9.23"
coreKtx = "1.13.1"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.3"
activityCompose = "1.9.0"
composeBom = "2024.06.00"
navVersion = "2.7.7"
hiltAndroid = "2.51.1"
room = "2.6.1"
hiltviewmodel = "1.0.0-alpha03"
hiltcom = "1.2.0"
dagger = "2.51.1"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycleRuntimeKtx" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navVersion" }
dagger-hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hiltAndroid" }
dagger-hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hiltAndroid" }
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
androidx-hilt-lifecycle-viewmodel = { group = "androidx.hilt", name = "hilt-lifecycle-viewmodel", version.ref = "hiltviewmodel" }
androidx-hilt-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "hiltcom" }
androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltcom" }
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
com-google-dagger = { id = "com.google.dagger.hilt.android", version.ref = "dagger" }
#android-library = { id = "com.android.library", version.ref = "agp" }
#kotlin-kapt = {id = "kapt", version.ref = "kapt" }
#devtools-ksp = {id = "com.google.devtools.ksp", version.ref = "ksp"}

Although the gradle sync succeeds, I get the following two errors when building my app:

e: This version (1.5.1) of the Compose Compiler requires Kotlin version 1.9.0 but you appear to be using Kotlin version 1.9.23 which is not known to be compatible.  Please consult the Compose-Kotlin compatibility map located at https://developer.android.com/jetpack/androidx/releases/compose-kotlin to choose a compatible version pair (or `suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!).
Execution failed for task ':app:checkDebugDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
   > Duplicate class org.intellij.lang.annotations.Identifier found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$AdjustableOrientation found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$BoxLayoutAxis found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$CalendarMonth found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$CursorType found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$FlowLayoutAlignment found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$FontStyle found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$HorizontalAlignment found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$InputEventMask found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$ListSelectionMode found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$PatternFlags found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$TabLayoutPolicy found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$TabPlacement found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$TitledBorderJustification found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$TitledBorderTitlePosition found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.JdkConstants$TreeSelectionMode found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.Language found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.MagicConstant found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.Pattern found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.PrintFormat found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.PrintFormatPattern found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.RegExp found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.intellij.lang.annotations.Subst found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.jetbrains.annotations.Nls found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.jetbrains.annotations.NonNls found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.jetbrains.annotations.NotNull found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.jetbrains.annotations.Nullable found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.jetbrains.annotations.PropertyKey found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)
     Duplicate class org.jetbrains.annotations.TestOnly found in modules annotations-12.0.jar -> annotations-12.0 (com.intellij:annotations:12.0) and annotations-23.0.0.jar -> annotations-23.0.0 (org.jetbrains:annotations:23.0.0)

Solution

  • The problems are caused by a faulty Compose, Hilt and Room setup. But let's go through that step by step.

    1. Since you said you wanted to use the newest versions, you should first update the Kotlin version in your version catalog. At the time of writing the newest version is:

      [versions]
      kotlin = "2.0.0"
      
    2. Then you need to update your Compose setup. That changed a bit with Kotlin 2.0.0:

      • The Compose compiler is now released together with Kotlin, so you need to add this plugin now to your version catalog:

        [plugins]   
        compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
        
      • Add the plugin to your top level gradle file's plugins block:

        alias(libs.plugins.compose.compiler) apply false
        
      • Add the plugin to your module level gradle file's plugins block:

        alias(libs.plugins.compose.compiler)
        
      • Remove this from your module level gradle file:

        composeOptions {
            kotlinCompilerExtensionVersion = "1.5.1"
        }
        
    3. Then you need to set up the ksp plugin. That is needed for other libraries that generate code during compile time, like Hilt and Room (ksp is the modern replacement for kapt, so kapt isn't needed):

      [versions]
      ksp = "2.0.0-1.0.23" # https://github.com/google/ksp/releases
      
      [plugins]
      devtools-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
      

      You need to make sure that the first part of the ksp version matches your Kotlin version. See here for a list of available ksp versions: https://github.com/google/ksp/releases

      You can now use this plugin in your gradle files in the plugins block.
      Project level:

      alias(libs.plugins.devtools.ksp) apply false
      

      Module level:

      alias(libs.plugins.devtools.ksp)
      
    4. Now you can set up Hilt. You have defined the version number twice in the version catalog, you should replace both dagger and hiltAndroid with hilt (because this is the Hilt version (not Dagger) and the version isn't Android specific). You should also rename hiltcom to hiltNavigationCompose to be more clear:

      [versions]
      hilt = "2.51.1"
      hiltNavigationCompose = "1.2.0"
      

      You already correctly defined the following libraries and plugins:

      [libraries]
      androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
      dagger-hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
      dagger-hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
      
      [plugins]
      com-google-dagger = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
      

      But you need to remove the following two libraries (and the version, and where they are used in your gradle files):

      [versions]
      hiltviewmodel = "1.0.0-alpha03"
      
      [libraries]
      androidx-hilt-lifecycle-viewmodel = { group = "androidx.hilt", name = "hilt-lifecycle-viewmodel", version.ref = "hiltviewmodel" }
      androidx-hilt-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "hilt" }
      

      You then need to add the plugin to your gradle files:

      // project:
      alias(libs.plugins.com.google.dagger) apply false
      // module (which you already have):
      alias(libs.plugins.com.google.dagger)
      

      And finally add the dependencies in the module level gradle file. You already have these:

      implementation(libs.dagger.hilt.android)
      implementation(libs.androidx.hilt.navigation.compose)
      

      But you need to change implementation(libs.dagger.hilt.android.compiler) to this:

      ksp(libs.dagger.hilt.android.compiler)
      

      Hilt should now be correctly set up in your build files. Make sure you add the additional setup as described here: https://developer.android.com/training/dependency-injection/hilt-android (Application class, AndroidManifest.xml, annotation of MainActivity)

    5. For the setup of Room you already have the proper libraries in your version catalog:

      [versions]
      room = "2.6.1"
      
      [libraries]
      androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
      androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
      

      You do not need androidx-room-runtime, that can be removed. Similar to Hilt, though, you need to replace implementation(libs.androidx.room.compiler) in your gradle file with this:

      ksp(libs.androidx.room.compiler)
      

    Your build files should be OK now. You may need to clean and rebuild your app after a gradle sync.