Android の app/build.gradle に kapt databindin

3ヶ月ぶりにメンテすることになった Android アプリのプロジェクトを現在(2018年10月)最新の Android Studio で開いてビルドしたらエラーになった。

その解決事例を記録しておく。

結論だけ言うと 「app/build.gradle の app/build.gradle の kapt '*.databinding:compiler:x.x.x' の行は消せ」 です。

0. 修正前の build.gradle

修正前の Project と app モジュールの build.gradle はこんな感じ。 3ヶ月前の時点で最新の Kotlin, Gradle, Support Libraries, ACC などを使っていた。

Project: build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.2.0'
    repositories {
        maven { url 'https://maven.google.com' }
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.github.gfx.ribbonizer:ribbonizer-plugin:2.1.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
        maven { url 'https://jitpack.io' }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

ext {
    playServicesVersion = "11.6.2"
    supportLibVersion = "26.1.0"
    runnerVersion = "1.0.1"
    rulesVersion = "1.0.1"
    espressoVersion = "3.0.1"
    archLifecycleVersion = "1.0.0"
    archRoomVersion = "1.0.0"
}

app: build.gradle

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

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "my.domain.awesomeapp"
        minSdkVersion 23
        targetSdkVersion 26
        versionCode 101
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
    }

    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }

        experiment {
            applicationIdSuffix ".exp"
            debuggable true
        }

        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    dataBinding {
        enabled = true
    }
}

dependencies {
    kapt 'com.android.databinding:compiler:3.1.2'

    implementation fileTree(dir: 'libs', include: ['*.jar'])
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })


    // Kotlin
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

    def coroutines_version = '0.20'
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

    // Android Support Libraries
    implementation 'com.android.support:design:' + rootProject.supportLibVersion
    implementation 'com.android.support:appcompat-v7:' + rootProject.supportLibVersion
    implementation 'com.android.support:cardview-v7:' + rootProject.supportLibVersion
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'

    // Google Play services
    implementation 'com.google.android.gms:play-services-maps:' + rootProject.playServicesVersion
    implementation 'com.google.android.gms:play-services-location:' + rootProject.playServicesVersion

    // retrofit & Gson
    implementation 'com.squareup.retrofit2:retrofit:2.1.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.3.1'
    implementation 'com.google.code.gson:gson:2.8.0'

    // DeployGate
    implementation 'com.deploygate:sdk:4.0.0'

    // Others
    implementation 'com.github.florent37:materialviewpager:1.2.3'
    implementation 'com.vividsolutions:jts-core:1.14.0'
    implementation 'com.annimon:stream:1.1.6'
    implementation 'com.squareup.picasso:picasso:2.5.2'
    implementation 'com.google.android:flexbox:0.3.1'

    // AAC
    implementation 'android.arch.lifecycle:extensions:' + rootProject.archLifecycleVersion
    implementation 'android.arch.persistence.room:runtime:' + rootProject.archRoomVersion
    annotationProcessor "android.arch.lifecycle:compiler:" + rootProject.archLifecycleVersion
    annotationProcessor "android.arch.persistence.room:compiler:" + rootProject.archRoomVersion

    // debot
//    debugCompile 'com.tomoima.debot:debot:2.0.3'
//    releaseCompile 'com.tomoima.debot:debot-no-op:2.0.3'
    implementation 'com.tomoima.debot:debot:2.0.3'

    // Rx, RxProperty
    implementation 'io.reactivex.rxjava2:rxjava:2.0.7'
    implementation 'io.reactivex.rxjava2:rxkotlin:2.1.0'
    implementation 'com.github.k-kagurazaka.rx-property-android:rx-property:4.0.0'
    implementation 'com.github.k-kagurazaka.rx-property-android:rx-property-kotlin:4.0.0'
    implementation 'com.jakewharton.rxrelay2:rxrelay:2.0.0'

    // Geo
    implementation 'ch.hsr:geohash:1.3.0'

    // Rutime permission
    implementation 'net.taptappun.taku.kobayashi:runtimepermissionchecker:1.0.4'

    testImplementation 'junit:junit:4.12'
}
repositories {
    mavenCentral()
    maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
}

//アイコン帯
ribbonizer {
    builder { variant, iconFile ->
        if (variant.buildType.name.equals("debug")) {
            // debug は緑
            return greenRibbonFilter(variant, iconFile)
        }
    }
}

1. Gradle の更新

現在最新の Android Studio(3.2.1) でこのプロジェクトを開いて Rebuild をしてみた

するとビルドの途中で「Gradle Plugin を 3.2.1 に、Gradle 自体を 4.6 に上げろ」と言ってくるので Update を押す。

Project: build.gradle は次のように書き換えられる。

-        classpath 'com.android.tools.build:gradle:3.1.2'
+        classpath 'com.android.tools.build:gradle:3.2.1'

また、gradle/wrapper/gradle-wrapper.properties も次のように更新される。

-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

2. Kotlin Gradle Plugin のエラー

  1. でビルドエラーが出る。内容は、

The Android Gradle plugin supports only Kotlin Gradle plugin version 1.2.51 and higher. Project 'my_awesomeapp' is using version 1.2.0.

Kotlin Gradle Plugin のバージョンが古いので 1.2.51 以上に上げてよ、ということなので、Project: build.gradle を次のように更新する。現在の Plugin の最新は 1.2.71 だったのでそうした。

-    ext.kotlin_version = '1.2.0'
+    ext.kotlin_version = '1.2.71'

3. Kapt のビルド(実行時?)エラー

もう一度 Rebuild する → エラーはでない。ここで安心してはいけない。 じゃあアプリ動かそー、と Run をすると Build エラーになる。

Run tasks > app::kaptDebugKotlin には次のように記録されている。

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:kaptDebugKotlin'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:103)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:73)
	at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59)
	at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59)
	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101)
	at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91)
	at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:256)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:249)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:238)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:663)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:597)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.api.GradleException: Compilation error. See log for more details
	at org.jetbrains.kotlin.gradle.tasks.TasksUtilsKt.throwGradleExceptionIfError(tasksUtils.kt:16)
	at org.jetbrains.kotlin.gradle.internal.KaptWithKotlincTask.compile(KaptWithKotlincTask.kt:79)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:46)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:788)
	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:755)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:124)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:113)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:95)
	... 33 more

なるほどぜんぜんわからん。 次に Kotlin compiler のエラーには ActivityXXXXBinding.java 全般で

my_awesomeapp/app/build/generated/data_binding_base_class_source_out/debug/dataBindingGenBaseClassesDebug/out/my_awesomeapp/databinding/ActivityMainBinding.java:120: エラー: シンボルを見つけられません
      @Nullable ViewGroup root, boolean attachToRoot, @Nullable DataBindingComponent component) {
                                                                ^
  シンボル:   クラス DataBindingComponent
  場所: クラス ActivityMainBinding

というエラーが出ており、DataBinding 関連のエラーであることが推察できる。

と、ここで

という情報があったことを思い出す。

そこで app: build.gradle の dependencies に書かれている kapt 'com.android.databinding:compiler:x.x.x' の行を削除した。

dependencies {
-    kapt 'com.android.databinding:compiler:3.1.2'

そして Rebuild > Run してみたところ、無事アプリが起動できた。

それにしても Kaptのビルドエラー群から「app/build.gradle に kapt *.databinding:compiler:x.x.x って書いちゃだめー」に辿り着くのは無理ゲー感がある。

ちなみに kapt 'com.android.databinding:compiler:3.1.2' のバージョンが古いだけで現在最新の 3.1.4 に書き換えれば問題ないのでは?と思ってやってみたけどエラー解消しなかった、やっぱこの行は消さないとダメっぽい。

この投稿もサラりと書いているが、アプリが起動できるようになるまで2時間以上を費やした。targetSdkVersion とか AAC や SupportLib, Playservices のバージョンが原因かと思っていろいろ弄り倒してたんだよね、 それらはすべて関係なかった という :sob: