kapt错误,Unsupported metadata version. Check that your Kotlin version is >= 1.0

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)
        }
    }
}

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

 if (!JvmMetadataVersion(
       header.metadataVersion,
       (header.extraInt and (1 shl 3)) != 0
    ).isCompatible()
) return null

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

严格模式:    需要生成的Metadatamajor==依赖的major1), 生成的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;
}

很明显,我们生成的mvmajor=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即可。 

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
这个问题可能是由于Kotlin的Kapt编译器插件引起的。Kapt是用于处理Kotlin注解处理器的工具。它可能会在编译过程中遇到问题导致错误。 首先,你可以尝试清理和重新构建项目,看看是否可以解决此问题。你可以使用以下命令清理项目: ``` ./gradlew clean ``` 然后,重新构建项目: ``` ./gradlew build ``` 如果这仍然无法解决问题,你可以尝试以下几个步骤: 1. 确保你的项目中使用的Kotlin版本和Kapt插件版本兼容。你可以在项目的`build.gradle`文件中查看这些版本信息,并确保它们与你的Kotlin代码库兼容。 2. 检查你的代码中是否存在任何错误或不兼容的注解处理器。某些注解处理器可能与Kapt不兼容,导致编译错误。如果有这样的注解处理器,请尝试暂时禁用它们并重新构建项目,看看问题是否得到解决。 3. 如果你最近升级了Kotlin或Kapt版本,请确保所有相关依赖项和插件都已正确更新。有时,版本不匹配可能会导致编译错误。 4. 检查你的项目中是否有任何缺少的依赖项。缺少依赖项可能会导致Kapt无法正常工作。请确保在项目的`build.gradle`文件中包含了所有必要的依赖项。 如果上述步骤都无法解决问题,你可以尝试在Stack Overflow等开发者社区寻求帮助,提供更详细的错误信息和项目配置,以便其他开发者能够更好地理解并解决你的问题。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值