java - unit - Error de compilación de Gradle: no se puede acceder al archivo de clase incorrecto de ITest: método predeterminado de ITest.class encontrado en el archivo de clase de la versión 50.0
unit test android (6)
Tengo un problema extraño y no sé cómo resolverlo.
Tengo una interfaz con el método por defecto, como este:
public interface ITest{
default String getText(){
return "ITest";
}
}
y la clase que implementa esta interfaz, como esta:
public class TestClasssss implements ITest{
private String text;
}
Y estoy tratando de usar esta clase dentro de mi proyecto de pruebas de unidades de aplicaciones.
Entonces, si copio estas clases dentro del proyecto de prueba unitaria de mi androide, se compila bien y todo funciona como se espera, sin embargo, si esta clase e interfaz se declaran en la carpeta fuente de la aplicación, la aplicación no se compila y falla.
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.
Entonces, ¿cómo podría solucionar este extraño comportamiento?
Mi configuración de graddle se ve así:
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''
}
¿Estás seguro de que tu compilación de gradle está utilizando jdk1.8 +? Parece que la compilación está tratando de utilizar una clase que se construyó con 1.8, pero se está probando durante la compilación con una versión inferior.
tratar:
gradle clean build
O
gradlew clean build
Asegúrese de configurar correctamente la compatibilidad de origen y destino
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Creo que probablemente necesites habilitar el compilador Jack
. Necesitas lo siguiente:
- Android Studio> 2.1
- Los métodos predeterminados solo están disponibles si está apuntando al nivel 24 de API
Tu gradle necesita verse algo como esto:
android {
...
defaultConfig {
...
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Esta es la página de características del lenguaje Java 8 en la documentación de Android
Estaba lidiando con el mismo problema, parece ser una especie de conflicto entre la versión de fuente java compilada aceptada en Android y la salida producida por el código compilado con retrolambda. El problema surge cuando se utiliza la notación default
para el método de interfaces funcionales. Hay algún tipo de soporte limitado para eso en el complemento retrolambda, citando el archivo Léame del repositorio ( orfjackal/retrolambda ):
retrolambda.defaultMethods Ya sea para realizar una copia de seguridad de los métodos predeterminados y los métodos estáticos en las interfaces. LIMITACIONES: Todas las interfaces con backported y todas las clases que las implementan o llaman a sus métodos estáticos deben ser backported juntas, con una ejecución de Retrolambda. Deshabilitado por defecto. Habilitar configurando "verdadero"
Así que puedes intentar usar esto en el archivo build.gradle
tu módulo build.gradle
:
...
android {
...
}
retrolambda {
defaultMethods = true
}
En mi caso, esto no funciona, pero mi escenario era muy diferente al tuyo. Tenía el código retrolambda en un proyecto de biblioteca y luego intentaba usarlo en otro proyecto de aplicación.
Además, no pude hacer funcionar el compilador Jack & Jill (hay algún tipo de soporte de java8 con Jack habilitado, vea Habilitar las características de Java 8 y Jack Toolchain en la referencia de Android), un "NullPointer" críptico aumenta en ./gradlew assembleDebug
, así que Sugiero evitar las jackOptions
por ahora.
¡Buena suerte!
Si está utilizando Android Studio, intente limpiar el proyecto, luego compile el proyecto. Si no ayuda también, haga clic en Archivo -> "Invalidar cachés / reiniciar". Debe ayudar
Tuve este problema después de usar dex2jar. De acuerdo con https://gitlab.ow2.org/asm/asm/blob/master/asm/src/main/java/org/objectweb/asm/Opcodes.java#L264 , la versión 50 del código de bytes de JVM representa Java 1.6, mientras que mi archivo dex fue diseñado para ejecutarse en la versión 52 (1.8). Utilicé otra utilidad dex2jar (que debería funcionar en cualquier jar, no solo dex) para cambiar la versión a 1.8. La fuente está en https://github.com/pxb1988/dex2jar/blob/2.x/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ClassVersionSwitch.java , el comando es d2j-class-version-switch.sh 8 <source jar> <destination jar>
.