2018/02/09

コマンドラインで gradle を実行すると com.android.tools.build:gradle が見つからないエラー

既存の Android プロジェクトを Android Studio 3.0.1 で読み込んだところ、
Android Studio ではビルド出来るのに、コマンドラインでは以下のようなエラーが出るようになってしまいました。

```console
`gutter: false;
$ ./gradlew tasks

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'MyApplication'.
> Could not resolve all files for configuration ':classpath'.
   > Could not find com.android.tools.build:gradle:3.0.1.
     Searched in the following locations:
         https://jcenter.bintray.com/com/android/tools/build/gradle/3.0.1/gradle-3.0.1.pom
         https://jcenter.bintray.com/com/android/tools/build/gradle/3.0.1/gradle-3.0.1.jar
     Required by:
         project :

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

BUILD FAILED in 0s
```

2016/05/28

"Gradle version x.xx is required" が出たときの対処方法

[Android Studio](https://developer.android.com/studio/index.html) を 2.1.1 にしたら以下のように [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin.html) のアップデートを促すダイアログが。
2016/01/12

Android Studio で Gradle wrapper をアップグレードする方法

Gradle wrapper は便利ですが、 場合によっては新しい機能を使うため等、Gradle のバージョンを上げなければならない時があります。
そんな時に Gradle wrapper で使用している Gradle のバージョンを上げる方法です基本的、ビルドが通っている間は無闇にビルドツールのバージョンを安易に変えるべきではありません

Gradle wrapper を使っていることを確認する

File → Settings → Build, Execution, Deployment → Build Tools → Gradle

Use default gradle wrapper (recommended) が選択されていることを確認します。

Gradle wrapper を更新する

プロジェクトのトップディレクトリで、以下を実行します。
2.8 のところは対象のバージョンに変更してください。

$ ${Android-studio}/gradle/gradle-2.8/bin/gradle wrapper --gradle-version 2.8

Android Studio でさらに更新する

この状態でプロジェクトのトップディレクトリ直下にある build.gradle を開きます。
すると、以下のようなメッセージが出るので、OK, apply suggestion! を押せばオーケーです

You can configure Gradle wrapper to use distribution with sources. It will provide IDE with Gradle API/DSL documentation.


2015/04/12

AndroidStudioで Java Library を追加したら UNEXPECTED TOP-LEVEL EXCEPTION でコンパイルが通らなかった場合の対処方法

現象

UNEXPECTED TOP-LEVEL EXCEPTION もいろいろなケースがあるので、一概に言えないのですが、以下のように ParseException: bad class file magic or version の場合、コンパイルに使った Java のバージョンが合っていない可能性が高いです。

...省略
:app:preDexDebug
AGPBI: {"kind":"SIMPLE","text":"UNEXPECTED TOP-LEVEL EXCEPTION:","position":{},"original":"UNEXPECTED TOP-LEVEL EXCEPTION:"}
AGPBI: {"kind":"SIMPLE","text":"com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)","position":{},"original":"com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:472)","position":{},"original":"\tat com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:472)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406)","position":{},"original":"\tat com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388)","position":{},"original":"\tat com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251)","position":{},"original":"\tat com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.dexer.Main.processClass(Main.java:704)","position":{},"original":"\tat com.android.dx.command.dexer.Main.processClass(Main.java:704)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.dexer.Main.processFileBytes(Main.java:673)","position":{},"original":"\tat com.android.dx.command.dexer.Main.processFileBytes(Main.java:673)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.dexer.Main.access$300(Main.java:83)","position":{},"original":"\tat com.android.dx.command.dexer.Main.access$300(Main.java:83)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:602)","position":{},"original":"\tat com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:602)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)","position":{},"original":"\tat com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)","position":{},"original":"\tat com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)","position":{},"original":"\tat com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.dexer.Main.processOne(Main.java:632)","position":{},"original":"\tat com.android.dx.command.dexer.Main.processOne(Main.java:632)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.dexer.Main.processAllFiles(Main.java:510)","position":{},"original":"\tat com.android.dx.command.dexer.Main.processAllFiles(Main.java:510)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.dexer.Main.runMonoDex(Main.java:280)","position":{},"original":"\tat com.android.dx.command.dexer.Main.runMonoDex(Main.java:280)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.dexer.Main.run(Main.java:246)","position":{},"original":"\tat com.android.dx.command.dexer.Main.run(Main.java:246)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.dexer.Main.main(Main.java:215)","position":{},"original":"\tat com.android.dx.command.dexer.Main.main(Main.java:215)"}
AGPBI: {"kind":"SIMPLE","text":"\tat com.android.dx.command.Main.main(Main.java:106)","position":{},"original":"\tat com.android.dx.command.Main.main(Main.java:106)"}
AGPBI: {"kind":"SIMPLE","text":"...while parsing com/kokufu/lib/Test.class","position":{},"original":"...while parsing com/kokufu/lib/Test.class"}
AGPBI: {"kind":"SIMPLE","text":"1 error; aborting","position":{},"original":"1 error; aborting"}

私の環境で Java のバージョンを調べてみると、以下のように 1.8 でした。

$ java -version
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)

解決方法

2015/4/12 現在、Android Studio は Java 1.7 系でコンパイルするようですので、以下のように Java Library のコンパイルバージョンを下げます。

lib/build.gradle
apply plugin: 'java'

sourceCompatibility = '1.7'

Android Application のコンパイルバージョンを変更する

おまけですが、Android Application の方のコンパイルバージョンも変更することが出来ます。
以下のように Source Compatibility を選択すればオーケー。
現時点では 1.8 が選択肢にないです。

File → Project Structure
2015/02/09

Gradle で Configuration with name 'default' not found. が出てしまった時の対処方法

Gradle で app と lib のように 2つの依存関係のあるモジュールを開発していると、以下のようなエラーが出てしまうことがあります。

A problem occurred configuring project ':app'.
> Cannot evaluate module lib : Configuration with name 'default' not found.

解決策1: app から対象の Configuration を明示的に指定する

Configuration は plugin を適用すると大抵は自動的に設定されます。 java とか com.android.application だと default という名前の Configuration があるので問題ないのですが、その他のものの場合は default がない場合があります。その場合は、対処の Configuration を以下のように明示的に指定することで回避することができます。
project の引数に path: が追加されているのに注意してください。

app/build.gradle
dependencies {
    compile project(path: ':lib', configuration: 'compile')
}

解決策2: lib に default という名前の Configuration を作る

lib にプラグインを適用してない等、Configuration がそもそもない場合は、以下のように自分で作成してしまうのも手です。

lib/build.gradle
configurations.create('default')
2014/07/22

compileSdkVersion を 'android-L' にすると INSTALL_FAILED_OLDER_SDK が発生する

Android Studio を 0.8.1 にして New Project を作成すると、app/build.gradle は以下のようになっています。

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

android {
    compileSdkVersion 'android-L'
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "com.kokufu.test"
        minSdkVersion 8
        targetSdkVersion 'L'
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
// 以下略

これ、そのままコンパイルすると、以下のようなエラーが発生してしまいます。
pkg: /data/local/tmp/com.kokufu.test
Failure [INSTALL_FAILED_OLDER_SDK]

もちろん、Android L (API 20, L preview) はインストールしてあります。

で、検索してみたところ、やっぱりバグみたいです。

というわけで、compileSdkVersion を 20 にしてやるとうまくコンパイル出来るようになりました。

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

android {
    compileSdkVersion 20
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "com.kokufu.test"
        minSdkVersion 8
        targetSdkVersion 20
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
// 以下略
2014/05/13

Aar をリリースしようとして artifact bundleRelease を使うとエラーになってしまう問題の回避方法

Gradle でビルドした成果物を Maven Repository に公開する方法が新しくなっていました。

まだ「試験的」な段階なので、即導入すべきものではないですが、aar と jar を同時に公開したい場合などに対応できそうなので試してみました。

build.gradle
apply plugin: 'android-library'
apply plugin: 'maven-publish'

android {
    // 省略
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
}

publishing {
    publications {
        aar(MavenPublication) {
            groupId 'com.kokufu.android.lib'
            artifactId 'sample-aar'
            version '1.0'

            artifact bundleRelease
        }
        jar(MavenPublication) {
            groupId 'com.kokufu.android.lib'
            artifactId 'sample-jar'
            version '1.0'

            artifact releaseJar
        }
    }
    repositories {
        maven {
            url "file:${projectDir}/maven-repo"
        }
    }
}

実行してみます。
$ ./gradlew publish

ところが、以下のようなエラーが。
* What went wrong:
A problem occurred configuring project ':SampleProject'.
> Cannot create a Publication named 'bundleRelease' because this container does not support creating elements by name alone. Please specify which subtype of Publication to create. Known subtypes are: MavenPublication

調べてみると、gradle android plugin 0.5.5 以降、"bundleRelease" という task は動的追加に変わったようです。

というわけで、artifact の実行を評価後にしてみました。

build.gradle
apply plugin: 'android-library'
apply plugin: 'maven-publish'

android {
    // 省略
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
}

publishing {
    publications {
        aar(MavenPublication) {
            groupId 'com.kokufu.android.lib'
            artifactId 'sample-aar'
            version '1.0'

            // artifact bundleRelease
        }
        jar(MavenPublication) {
            groupId 'com.kokufu.android.lib'
            artifactId 'sample-jar'
            version '1.0'

            // artifact releaseJar
        }
    }
    repositories {
        maven {
            url "file:${projectDir}/maven-repo"
        }
    }
}

afterEvaluate {
    publishing.publications.aar.artifact(bundleRelease)
    publishing.publications.jar.artifact(packageReleaseJar)
}

これで問題なく公開されるようになりました。
少々強引な気がします。他に良い方法をご存知の方は是非教えてください。

このへんは、android-library も Gradle も流動的な仕様のようですので、あまり深追いしな方が良いかもしれません。
また、すぐ使えなくなっちゃいそうですから。

ちなみに、しれっと書いていますが、releaseJar で jar ファイルも一緒に公開しています。


環境
Gradle 1.10
gradle android plugin 0.9.0