Android StudioがやってくれたKotlinの初期設定がGradle Syncできない

2017.4.13更新
----------

下記の記事で紹介したとおり、Gradle Plugin for Android v2.2.0以降ではsdk-manager-pluginを使う必要がなくなったため、全く同じ理由でこの問題が起きることはなくなりました。

* [CI環境でAndroid SDKのダウンロードを自動化する2016 - Qiita](http://qiita.com/Nkzn/items/b9a0ddd1345fb78d7d44)

はじめに
----------

社内向けのテンプレートプロジェクトにKotlin設定を適用しようと思ったら躓きました。build.gradleを初期状態から弄ってある人がハマりやすい罠だったので、備忘録として残しておきます。

※Android Studioでしか検証していないので、Intellij IDEAでの動きが気になる方は各自お願いします。

環境
----------

* Android Studio: バージョン1.1.0
* Kotlin Plugin: バージョン0.11.91.AndroidStudio.4
* プロジェクト： [WaterCell/android-app-template](https://github.com/WaterCell/android-app-template)


現象
----------

* [Gradleを使ってAndroidプロジェクトにKotlinを導入する](http://qiita.com/ngsw_taro/items/e2d9f294cb974b9fce68)

上記の記事で紹介されている通り、Kotlin Pluginを導入済みのAndroid Studioであれば、普通のAndroidアプリケーションプロジェクトにKotlinファイルを置いただけでKotlin向けの各種設定をするかどうかを訊いてくれます。

![スクリーンショット 2015-04-03 9.37.18.png](https://qiita-image-store.s3.amazonaws.com/0/2276/42465551-57f3-c5ad-64cd-83841b39a1c7.png "スクリーンショット 2015-04-03 9.37.18.png")

ですが、ここで設定した内容そのままでGradle Syncを行うと・・・

```
Error:(2, 0) Extension with name 'android' does not exist. Currently registered extension names: [ext, idea]
```

エラーが出てしまいました。

検証
----------

新規作成したプロジェクトに同様の操作を行った場合には問題なくGradle Syncやビルドができましたので、IDEやプラグインではなく、元にしたプロジェクトの設定内容に問題がありそうです。

### 問題ないパターン

#### before

```gradle:app/build.gradle
apply plugin: 'com.android.application'
...
```

#### after

```gradle:app/build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
...
```

### 問題が起きたパターン

#### before

```gradle:app/build.gradle
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.application'
...
```

#### after

```gradle:app/build.gradle
apply plugin: 'android-sdk-manager'
apply plugin: 'kotlin-android'
apply plugin: 'com.android.application'
...
```

原因
----------

### 前提条件

`apply plugin: 'kotlin-android'` は `apply plugin: 'com.android.application'` に依存しています。なので、 `apply plugin: 'com.android.application'` は必ず先に書かないといけません。

### 状況分析

問題が起きたパターンでは、applyの順序が逆転してしまっています。前述のエラーメッセージは、Androidのプラグインが読み込まれていないことへの苦情だったようです。

「apply群の2行目に `apply plugin: 'kotlin-android'` を入れる」という処理に決め打ちされているとこういうことになりそうですが、該当コードを読みに行ってもちょっと分かりませんでした。

* [あやしいところ1](https://github.com/JetBrains/kotlin/blob/3a04bd7e44525e813e5e51e29281ab0519a428dc/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinAndroidGradleModuleConfigurator.java)
* [あやしいところ2](https://github.com/JetBrains/kotlin/blob/3a04bd7e44525e813e5e51e29281ab0519a428dc/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithGradleConfigurator.java#L122-L131)

1行目には `apply plugin: 'com.android.application'` が来るケースのほうが多いと思うので、決め打ちされていても普通は問題無いです。

#### 今回は何故ハマったのか

CI環境設定の簡便化を目的に、[JakeWharton/sdk-manager-plugin](https://github.com/JakeWharton/sdk-manager-plugin)を使っていたためです。

> Apply the plugin in your build.gradle before the regular 'android' plugin:

sdk-manager-pluginでは、Androidプラグインより先にapplyすることが求められています。

同様のapply順を求めてくるプラグインでも、同じことが起きると思います。

解決
----------

```gradle:app/build.gradle
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
...
```

順番を入れ替えたら行けました。

まとめ
---------

sdk-manager-pluginをお使いの皆様は気をつけましょう。

それでは皆様、素晴らしいKotlinライフを！

宣伝
---------

ウォーターセル株式会社では、農業分野でのITツールの開発・改善に一緒に取り組んでくれるAndroid/iOSエンジニアを募集しています。
農業IT分野がどんなものなのか話を聞いてみたいレベルでも結構ですので、興味のある方は@Nkznまで空リプを飛ばすなり何なりして、コンタクトを取っていただければと幸いです。