Caused by: java.lang.IllegalStateException: Unsupported metadata version. Check that your Kotlin version is >= 1.0

at dagger.internal.codegen.kotlin.KotlinMetadata.metadataOf(KotlinMetadata.java:206)

at dagger.internal.codegen.kotlin.KotlinMetadata.from(KotlinMetadata.java:186)

at dagger.internal.codegen.kotlin.KotlinMetadataFactory.create(KotlinMetadataFactory.java:56)

at dagger.internal.codegen.kotlin.KotlinMetadataUtil.isCompanionObjectClass(KotlinMetadataUtil.java:100)

at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:116)

at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:59)

at dagger.internal.codegen.validation.TypeCheckingProcessingStep.lambda$process$0(TypeCheckingProcessingStep.java:51)

at com.google.common.collect.SingletonImmutableBiMap.forEach(SingletonImmutableBiMap.java:65)

at dagger.internal.codegen.validation.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:48)

at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:104)

at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:59)

at dagger.shaded.auto.common.BasicAnnotationProcessor$ProcessingStepAsStep.process(BasicAnnotationProcessor.java:495)

at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:228)

at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:208)

at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt:90)

at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:166)

at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:980)

... 41 more

更新Dagger版到2.46即可解决该问题。

在开始分析前因后果之前,我们先对metadata做个简单了解。

任何经过Kotlin/JVM编译器编译生成的class文件,都会带有@Metadata注解,如下是一个.kt文件生成的字节码反编译后的java代码

@Module

@Metadata(

mv = {1, 9, 0},

k = 1,

d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\b\u0007\u0018\u0000 \u00032\u00020\u0001:\u0001\u0003B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0004"},

d2 = {"Lcom/example/doudindemo/AnimalsModule;", "", "()V", "Companion", "doudindemo_debug"}

)

public final class AnimalsModule {

}

Kotlin.Metadata类中解释了每个属性的作用:

mv :编译时的元数据版本, 一般和kotlin 插件版本走,比如我现在用的kotlin 1.9.22, mv就是{1,9,0},  基本上就是mojor,minor

k :表明这个注解编码的元数据的种类,比如1是Class,2是File等, 超出范围的值就被当做非kotlin文件。

d1,d2 :根据k不同而不同

之所以这样简短命名,是为了减小生成的文件的大小。

那么生成的@Metadata有什么用呢?

字节码混淆器或者注解预处理器会用到,他们需要读取或修改metadata,为了简化样板代码和重复造轮子, kotlinx-metadata-jvm库就诞生了,提供了一套标准工具类。

现在我们回过头来看上面的错误,原因就是项目引用的Dagger库(2.26),它也使用了kotlinx-metadata-jvm库(0.1.0)来处理@Metadata注解,但是metadata库版本比较老,不支持当前编译环境生成的class文件中的Metadata,就好比我最多只支持java6, 你给我来个java 8, 我干不了。

那具体是怎么不支持呢?又是不支持哪个属性?

接下来需要看源码了,我们首先定位报错位置

Caused by: java.lang.IllegalStateException: Unsupported metadata version. Check that your Kotlin version is >= 1.0

        at dagger.internal.codegen.kotlin.KotlinMetadata.metadataOf(KotlinMetadata.java:206)

KotlinClassMetadata metadata = KotlinClassMetadata.read(header);

if (metadata == null) {

// Should only happen on Kotlin < 1.0 (i.e. metadata version < 1.1)

throw new IllegalStateException(

"Unsupported metadata version. Check that your Kotlin version is >= 1.0");

}

这里就是编译报错的信息位置,由此可见,KotlinClassMetadata.read(header)返回了null, 接着看为什么返回null。

//kotlinx.metadata.jvm.KotlinClassMetadata.kt

companion object {

/**

* Reads and parses the given header of a Kotlin JVM class file and returns the correct type of [KotlinClassMetadata] encoded by

* this header, or `null` if this header encodes an unsupported kind of Kotlin classes or has an unsupported metadata version.

*

* Throws [InconsistentKotlinMetadataException] if the metadata has inconsistencies which signal that it may have been

* modified by a separate tool.

*

* @param header the header of a Kotlin JVM class file to be parsed

*/

@JvmStatic

fun read(header: KotlinClassHeader): KotlinClassMetadata? {

// We only support metadata of version 1.1.* (this is Kotlin from 1.0 until today)

if (!JvmMetadataVersion(

header.metadataVersion,

(header.extraInt and (1 shl 3)/* see JvmAnnotationNames.METADATA_STRICT_VERSION_SEMANTICS_FLAG */) != 0

).isCompatible()

) return null

return try {

when (header.kind) {

KotlinClassHeader.CLASS_KIND -> KotlinClassMetadata.Class(header)

KotlinClassHeader.FILE_FACADE_KIND -> KotlinClassMetadata.FileFacade(header)

KotlinClassHeader.SYNTHETIC_CLASS_KIND -> KotlinClassMetadata.SyntheticClass(header)

KotlinClassHeader.MULTI_FILE_CLASS_FACADE_KIND -> KotlinClassMetadata.MultiFileClassFacade(header)

KotlinClassHeader.MULTI_FILE_CLASS_PART_KIND -> KotlinClassMetadata.MultiFileClassPart(header)

else -> KotlinClassMetadata.Unknown(header)

}

} catch (e: InconsistentKotlinMetadataException) {

throw e

} catch (e: Throwable) {

throw InconsistentKotlinMetadataException("Exception occurred when reading Kotlin metadata", e)

}

}

}

这里会判断生成class的Metadata版本是否兼容, 不兼容返回null

if (!JvmMetadataVersion(

       header.metadataVersion,

       (header.extraInt and (1 shl 3)) != 0

).isCompatible()

) return null

是否兼容的要求(满足其中一条):

严格模式:    需要生成的Metadata的major==依赖的major(1), 生成的minor <= 依赖的minor(1)

非严格模式: 需要生成的Metadata中的major==1, minor<=4才算兼容

//kotlinx.metadata.internal.metadata.jvm.deserialization.JvmMetadataVersion.java

//依赖的metadata版本, major=1, minor=1

public static final JvmMetadataVersion INSTANCE = new JvmMetadataVersion(new int[]{1, 1, 15});

public boolean isCompatible() {

return (this.getMajor() != 1 || this.getMinor() != 0) && (this.isStrictSemantics ? this.isCompatibleTo((BinaryVersion)INSTANCE) : this.getMajor() == 1 && this.getMinor() <= 4);

}

//kotlinx.metadata.internal.metadata.deserialization.BinaryVersion.java

protected final boolean isCompatibleTo(@NotNull BinaryVersion ourVersion) {

Intrinsics.checkParameterIsNotNull(ourVersion, "ourVersion");

return this.major == 0 ? ourVersion.major == 0 && this.minor == ourVersion.minor : this.major == ourVersion.major && this.minor <= ourVersion.minor;

}

很明显,我们生成的mv是major=1, minor=9, 没有满足兼容性要求

@Metadata(

   mv = {1, 9, 0},

   k = 1

}

更新Dagger版到2.46即可,

implementation  'com.google.dagger:dagger:2.46'

implementation  'com.google.dagger:dagger-android:2.46'

kapt 'com.google.dagger:dagger-android-processor:2.46'

kapt 'com.google.dagger:dagger-compiler:2.46'

 更新后我们再看看之前报错的地方

这个版本和之前报错的地方metadataOf方法大致一样,

KotlinClassMetadata metadata = KotlinClassMetadata.read(header);

然后这里不会返回null了,因为它也更新了自己的kotlinx-metadata-jvm库,比如0.7.0, 再看read方法:

//kotlinx.metadata.jvm.KotlinClassMetadata.kt

@JvmStatic

fun read(annotationData: Metadata): KotlinClassMetadata {

checkMetadataVersionForRead(annotationData)

return wrapIntoMetadataExceptionWhenNeeded {

when (annotationData.kind) {

CLASS_KIND -> Class(annotationData)

FILE_FACADE_KIND -> FileFacade(annotationData)

SYNTHETIC_CLASS_KIND -> SyntheticClass(annotationData)

MULTI_FILE_CLASS_FACADE_KIND -> MultiFileClassFacade(annotationData)

MULTI_FILE_CLASS_PART_KIND -> MultiFileClassPart(annotationData)

else -> Unknown

}

}

}

即使识别不了k属性,也只会返回Unknown Metadata对象而不是null, checkMetadataVersionForRead()检查版本也只要求生成的major<2即可。 

推荐链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: