Lambda 在 Android 库模块中导致编译器异常
Lambda causes compiler exception in Android Library Module
当我在 Android 库模块中使用 lambda 表达式时,我收到编译器异常 com.sun.tools.javac.code.Symbol$CompletionFailure: class file for java.lang.invoke.MethodType not found
。
Lambda 表达式在 Android 应用程序模块中使用时编译无误。
可在此处找到演示该问题的示例项目:
https://github.com/adamdye/AndroidLambdaIssue
示例中有趣的 class 是 MyLibrary.java 和 MainActivity.java。每个 class 包含相同的表达式。
设置
Android Studio 2.2 preview 1
min/target SDK version = android-N
build tools version = 24.0.0.rc4
jack compiler enabled
source/target compatibility = 1.8
Gradle version = 2.10
Android Plugin Version = 2.2.0-alpha1
JDK = java 8
我对使用 retro-lambda 不感兴趣。我想通过适当的配置让它工作。我假设我在某处错过了一步。
只是回过头来,添加我学到的东西。
通过将我的 JAVA HOME 的运行时 jar 添加到项目 build.gradle 文件中 gradle 的引导类路径,我能够克服 MethodType not found
错误。
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xbootclasspath/a:" + System.properties.get("java.home") + "/lib/rt.jar"
}
}
}
但是,应用程序不会部署到设备或模拟器,因为 app:transformClassesWithPreJackPackagedLibrariesForDebug
gradle 任务失败。它要求所有用作 lamba 的接口都在类路径上。 bootclasspath 修复没有为 Jack 编译器设置类路径,并且库还没有使用 Jack 编译器。
我打开了一个关于这个问题的错误报告:https://code.google.com/p/android/issues/detail?id=211386
他们评论说,这将在不久的将来得到解决。
我通过包含包含 Java 源的 JAR 作为依赖项而不是编译的 JAR 来解决问题。这就是我配置项目的方式:
在图书馆的 build.gradle
:
configurations {
sources
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.java.srcDirs
}
artifacts {
sources sourcesJar
}
在应用程序中 build.gradle
:
dependencies {
compile project(path: ":gdxstudio-core", configuration: "sources")
当然,该库作为外部项目包含在应用程序的 settings.gradle
中
当我在 Android 库模块中使用 lambda 表达式时,我收到编译器异常 com.sun.tools.javac.code.Symbol$CompletionFailure: class file for java.lang.invoke.MethodType not found
。
Lambda 表达式在 Android 应用程序模块中使用时编译无误。
可在此处找到演示该问题的示例项目:
https://github.com/adamdye/AndroidLambdaIssue
示例中有趣的 class 是 MyLibrary.java 和 MainActivity.java。每个 class 包含相同的表达式。
设置
Android Studio 2.2 preview 1
min/target SDK version = android-N
build tools version = 24.0.0.rc4
jack compiler enabled
source/target compatibility = 1.8
Gradle version = 2.10
Android Plugin Version = 2.2.0-alpha1
JDK = java 8
我对使用 retro-lambda 不感兴趣。我想通过适当的配置让它工作。我假设我在某处错过了一步。
只是回过头来,添加我学到的东西。
通过将我的 JAVA HOME 的运行时 jar 添加到项目 build.gradle 文件中 gradle 的引导类路径,我能够克服 MethodType not found
错误。
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xbootclasspath/a:" + System.properties.get("java.home") + "/lib/rt.jar"
}
}
}
但是,应用程序不会部署到设备或模拟器,因为 app:transformClassesWithPreJackPackagedLibrariesForDebug
gradle 任务失败。它要求所有用作 lamba 的接口都在类路径上。 bootclasspath 修复没有为 Jack 编译器设置类路径,并且库还没有使用 Jack 编译器。
我打开了一个关于这个问题的错误报告:https://code.google.com/p/android/issues/detail?id=211386
他们评论说,这将在不久的将来得到解决。
我通过包含包含 Java 源的 JAR 作为依赖项而不是编译的 JAR 来解决问题。这就是我配置项目的方式:
在图书馆的 build.gradle
:
configurations {
sources
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.java.srcDirs
}
artifacts {
sources sourcesJar
}
在应用程序中 build.gradle
:
dependencies {
compile project(path: ":gdxstudio-core", configuration: "sources")
当然,该库作为外部项目包含在应用程序的 settings.gradle