Retrolambda+Robolectricでテストを動かす為にtask.name ==~ /compileTest.*Java/をフックしているのにcom.sun.tools.javac.code.Symbol$CompletionFailure: java.lang.invoke.MethodTypeが見つからずエラーになる問題
タイトル長いな。
問題
Retrolambda+Robolectricでテストを動かす為に以下の様なコードをbuild.gradleに書く必要があります。正規表現で一致するタスクの時にビルドパスをretrolambdaに向けたり、コンパイラをJava8に変更するコードです。
参考 : Android - λ... < ユニットテストのテストコード上で Retrolambda が使えない - Qiita
tasks.withType(Test) {
project.tasks
.findAll {
task -> (task.name ==~ /compileTest.*Java/ )
}
.each { task ->
task.doFirst {
def buildPath = "$project.buildDir/retrolambda"
def jarPath = "$buildPath/$project.android.compileSdkVersion"
def javac = "${project.retrolambda.tryGetJdk()}/bin/javac"
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
options.fork = true
options.compilerArgs += ["-bootclasspath", "$jarPath/android.jar"]
options.forkOptions.executable = javac
}
}
}
しかし、android gradle pluginが1.1.0以上の環境ではcom.sun.tools.javac.code.Symbol$CompletionFailure: java.lang.invoke.MethodTypeが見つからずエラーになってしまいます。
原因
android gradle plugin1.1.0からJVMを利用したUnit Testをサポートしました。それに伴いTestのコンパイル時のタスク名が変わりました。
compileTestDebugJava -> compileDebugUnitTestJava
AndroidTestの場合はcompileDebugAndroidTestJavaという風に変わっています。
対応
タスクをフックする正規表現を更新すればオッケーです。
tasks.withType(Test) {
project.tasks
.findAll {
task -> (task.name ==~ /compile.*?TestJava/)
}
.each { task ->
task.doFirst {
def buildPath = "$project.buildDir/retrolambda"
def jarPath = "$buildPath/$project.android.compileSdkVersion"
def javac = "${project.retrolambda.tryGetJdk()}/bin/javac"
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
options.fork = true
options.compilerArgs += ["-bootclasspath", "$jarPath/android.jar"]
options.forkOptions.executable = javac
}
}
}
まとめ
この辺の追従って大変だなー