我想在我的android项目中同时使用evant/gradle-retrolambda和RoboBinding/RoboBinding。
将RoboBinding添加到项目时,您可以选择使用RoboBinding/RoboBinding-aspectj-plugin与AspectJ一起使用。但是,每当我打开它时,我的代码中的lambda表达式都会产生这个编译错误:
Error:error at (no source information available)
/mnt/FCEE58DAEE588F30/AndroidstudioProjects/SpeechACall/app/src/main/java/com/voicesense/personality_profiling_dialer/GcmRegistrationHandler.java:1:0::0 The type java.lang.invoke.MethodHandles cannot be resolved. It is indirectly referenced from required .class files
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compileDebugAspectJ'.
> The type java.lang.invoke.MethodHandles cannot be resolved. It is indirectly referenced from required .class files
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
这是我的build.gradle
文件
buildscript {
repositories {
mavenCentral()
maven() {
name 'RoboBinding AspectJPlugin Maven Repository'
url "https://github.com/RoboBinding/RoboBinding-aspectj-plugin/raw/master/mavenRepo"
}
}
dependencies {
classpath 'me.tatarka:gradle-retrolambda:2.4.1'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.+'
classpath 'org.robobinding:aspectj-plugin:0.8.+'
}
}
repositories {
mavenCentral()
}
apply plugin: 'retrolambda'
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
apply plugin: 'org.robobinding.android-aspectj'
android {
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
applicationId "com.voicesense.hr_dialer"
minSdkVersion 15
targetSdkVersion 21
}
signingConfigs {
release {
storeFile file("../../../../../../home/amitai/personality-profiling-dialer_key.keystore")
storePassword System.getenv("KSTOREPWD")
keyAlias "alias_name"
keyPassword System.getenv("KEYPWD")
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt'
signingConfig signingConfigs.release
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
retrolambda {
jvmArgs '-noverify'
}
ext {
//robobindingVersion = 'latest.integration'
robobindingVersion = '0.8.9'
}
dependencies {
compile files('libs/acra-4.5.0.jar')
compile files('libs/ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar')
compile 'com.google.android.gms:play-services:6.1.71'
compile 'com.android.support:support-v4:21.0.3'
compile 'com.android.support:support-v13:20.0.0'
//compile 'com.netflix.rxjava:rxjava-android:0.20.7'
compile 'io.reactivex:rxandroid:0.24.0'
//compile 'com.googlecode.libphonenumber:geocoder:2.16'
compile 'com.googlecode.libphonenumber:libphonenumber:7.0'
compile ("org.robobinding:robobinding:$robobindingVersion:with-aop-and-dependencies") {
exclude group: 'com.google.guava', module: 'guava'
}
aspectPath ("org.robobinding:robobinding:$robobindingVersion:with-aop-and-dependencies") {
exclude group: 'com.google.guava', module: 'guava'
}
apt "org.robobinding:codegen:$robobindingVersion"
}
here是一个压缩的Android Studio项目,可用于重现(包含相关的build.gradle
文件和无法编译的lambda表达式。)
经过一番调查后,我发现它与AspectJ不兼容Java 8。 我相信Java 8 Compatiblity/Update AspectJ · Issue #22 · JakeWharton/hugo和Java 8 not supported · Issue #6 · uPhyca/gradle-android-aspectj-plugin有同样的问题。有什么建议吗?
答案 0 :(得分:0)
我使用retrolambda制作了自己的插件支持aspectj。 GradleAndroidAspectJPlugin
当项目使用retrolambda时。在编译retrolamda之后,你必须使用ant iajc重新编译类。
project.configurations {
aspectjTaskClasspath
aspectsInPath
}
project.repositories {
mavenCentral()
}
def aspectjVersion = '1.8.5';
project.dependencies {
//AspectJ
aspectjTaskClasspath "org.aspectj:aspectjtools:$aspectjVersion"
compile "org.aspectj:aspectjrt:$aspectjVersion"
}
project.afterEvaluate {
project.android.applicationVariants.all { variant ->
def buildTypeName = variant.name.capitalize()
def hasRetrolambda = project.plugins.hasPlugin('me.tatarka.retrolambda')
def copyDir = new File("${project.buildDir.absolutePath}/copyClasses")
if (copyDir.exists()) {
copyDir.deleteDir()
}
copyDir.mkdirs()
def copyClassTask = project.task("copy${buildTypeName}Classes", type: Copy) {
from variant.javaCompile.destinationDir
into copyDir
doLast {
variant.javaCompile.destinationDir.deleteDir()
variant.javaCompile.destinationDir.mkdirs()
}
}
def aspectsInPaths = [];
def aspectsInPathsAbsolute = [];
def aopTask = project.task("compile${buildTypeName}AspectJ") {
doFirst {
project.configurations.aspectsInPath.each {
aspectsInPaths.add(it);
aspectsInPathsAbsolute.add(it.absolutePath);
}
}
doLast {
ant.taskdef(
resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties",
classpath: project.configurations.aspectjTaskClasspath.asPath
)
ant.iajc(
source: project.android.compileOptions.sourceCompatibility,
target: project.android.compileOptions.targetCompatibility,
fork: "true",
destDir: variant.javaCompile.destinationDir,
bootClasspath: project.android.bootClasspath.join(File.pathSeparator),
inpathDirCopyFilter: "java/**/*.class"
) {
classpath {
variant.javaCompile.classpath.each {
if (!aspectsInPathsAbsolute.contains(it)) {
pathElement(location: it)
}
}
}
inpath {
pathElement(location: copyDir)
aspectsInPaths.each {
if (!it.name.startsWith("aspectjrt")) {
pathElement(location: it)
}
}
}
}
}
}
aopTask.dependsOn(copyClassTask);
def filterPreDexTask = project.task("filter${buildTypeName}PreDex") {
doLast {
def finalPreDexJars = []
project.tasks["preDex${buildTypeName}"].inputFiles.each {
if (it.name.startsWith("aspectjrt") ||
!aspectsInPathsAbsolute.contains(it.absolutePath)) {
finalPreDexJars.add(it)
}
}
project.tasks["preDex${buildTypeName}"].inputFiles = finalPreDexJars
}
}
project.tasks["preDex${buildTypeName}"].dependsOn(filterPreDexTask)
if (hasRetrolambda) {
project.tasks["compileRetrolambda$buildTypeName"].finalizedBy(aopTask)
} else {
project.tasks["compile${buildTypeName}Java"].finalizedBy(aopTask)
}
}
}