Gradle 构建错误:无法访问 ITest 坏类文件:ITest.class在 V50.0 类文件中找到的默认方法

我有奇怪的问题,不知道如何解决它。

我有一个带有默认方法的接口,如下所示:

public interface ITest{
    default String getText(){
       return "ITest";
    }
}

和实现此接口的类,如下所示:

public class TestClasssss implements ITest{
    private String text;
}

我试图在我的应用单元测试项目中使用这个类。

因此,如果我在Android的单元测试项目中复制这些类,它可以编译正常并且全部按预期工作,但是如果该类和接口在应用程序源文件夹中声明,则应用程序不会编译并崩溃

Error:(30, 10) error: cannot access ITest bad class file: ~\ITest.class
default method found in version 50.0 classfile
Please remove or make sure it appears in the correct subdirectory of the classpath.

那么,我该如何解决这种奇怪的行为呢?


我的 graddle 配置如下所示:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'me.tatarka:gradle-retrolambda:3.2.5'
    }
}

repositories {
    mavenCentral()
    mavenLocal()
    maven {
        url = "https://oss.sonatype.org/content/repositories/snapshots/"
    }
    jcenter()
}

apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'realm-android'
apply plugin: 'com.neenbedankt.android-apt'

apt {
    arguments {
        androidManifestFile variant.outputs[0]?.processResources?.manifestFile
    }
}

android {
    compileSdkVersion 24
    buildToolsVersion '24.0.1'

    defaultConfig {
        applicationId "io.projectname"
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        debug {
            debuggable true
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt')
        }
    }

    testOptions {
        unitTests.returnDefaultValues = true
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    dataBinding {
        enabled = true
    }

    sourceSets {
        main {
            res.srcDirs =
                    [
                            'src/main/res/controls',
                            'src/main/res/fragments',
                            'src/main/res/activities',
                            'src/main/res/views',
                            'src/main/res'
                    ]
        }
    }
}

ext {
    JUNIT_VERSION = '4.12'
    DAGGER_VERSION = '2.2'
}

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

    testCompile 'junit:junit:4.12'
    testCompile 'org.mockito:mockito-core:2.0.111-beta'
    testCompile "org.robolectric:robolectric:3.1.1"

    compile 'com.android.support:appcompat-v7:24.2.0'
    compile 'com.android.support:design:24.2.0'
    compile 'com.roughike:bottom-bar:1.3.4'
    compile 'com.aurelhubert:ahbottomnavigation:1.2.3'
    compile 'joda-time:joda-time:2.9.4'
    compile 'com.annimon:stream:1.0.9'
    compile 'com.kyleduo.switchbutton:library:1.4.1'
    compile 'io.reactivex:rxandroid:1.2.0'
    compile 'io.reactivex:rxjava:1.1.5'
    compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
    compile('eu.davidea:flexible-adapter:5.0.0-SNAPSHOT') {
        changing = true
    }
    compile 'com.github.aakira:expandable-layout:1.5.1@aar'
    compile "cn.aigestudio.wheelpicker:WheelPicker:1.1.2"
    compile 'net.sf.biweekly:biweekly:0.5.0'

    //Dagger dependencies started
    compile "com.google.dagger:dagger:$DAGGER_VERSION"
    apt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
    provided 'javax.annotation:jsr250-api:1.0'
    compile 'javax.inject:javax.inject:1'
    testCompile "junit:junit:$JUNIT_VERSION"
    testApt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
    //Dagger dependencies finished

    provided 'org.projectlombok:lombok:1.16.10'
}

答案 1

确保正确设置了源和目标兼容性

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

答案 2

我正在处理同样的问题,它似乎是Android上接受的已编译Java源代码版本与使用retrolambda编译的代码生成的输出之间的某种冲突。当您使用函数接口方法的表示法时,问题就出现了。在 retrolambda 插件中对此有某种有限的支持,引用了存储库的自述文件(orfjackal/retrolambda):default

retrolambda.defaultmethods 是否在接口上向后移植默认方法和静态方法。限制:所有向后移植的接口和所有实现它们或调用其静态方法的类必须一起向后移植,并执行一次 Retrolambda。默认情况下禁用。通过设置为“true”来启用

因此,您可以尝试在Android模块的文件中使用它:build.gradle

...
android {
...
}
retrolambda {
    defaultMethods = true
}

在我的情况下,这不起作用,但我的场景与你的情况完全不同。我在一个库项目上有 retrolambda 代码,然后尝试在另一个应用项目上使用它。

另外,我无法让Jack & Jill编译器工作(在启用Jack的情况下有某种java8支持,请参阅在android参考中启用Java 8功能和Jack Toolchain),一个神秘的“NullPointer”在,所以我建议现在避免。./gradlew assembleDebugjackOptions

祝你好运!


推荐