Gradle插件自定义任务调用kotlinx serialization找不到类序列化器问题
问题根因
- 你遇到的报错核心是类加载器隔离问题:Gradle任务运行在Gradle守护进程的独立类加载环境中,和目标项目的类加载器完全隔离。kotlinx-serialization编译器插件为
@Serializable类生成的序列化器类,只存在于目标项目的编译输出路径下,默认不会被Gradle任务的类加载器加载,所以调用serializer()时找不到对应实现。 - 你在目标项目中直接运行相同代码不报错,是因为此时用的是目标项目自身的应用类加载器,已经加载了全部编译产物包括生成的序列化器类。
需补充的配置
1. 自定义任务中构造目标项目专属类加载器
执行反射扫描、获取序列化器的逻辑前,先构造包含目标项目编译输出、运行时依赖的类加载器,并且所有目标类都通过这个类加载器加载:
import java.net.URLClassLoader // 收集目标项目的主源码集运行时全类路径 val projectClasspath = project.sourceSets.main.runtimeClasspath.files .map { it.toURI().toURL() } .toTypedArray() // 构造类加载器,父加载器复用当前任务的类加载器 val targetClassLoader = URLClassLoader(projectClasspath, this::class.java.classLoader) // 切换当前线程上下文类加载器,避免序列化内部逻辑用错加载器 Thread.currentThread().contextClassLoader = targetClassLoader // 注意:扫描到的类必须用targetClassLoader加载,不要用任务默认的类加载器 val clazz = targetClassLoader.loadClass("目标类全限定名") // 此时调用即可正常获取序列化器 val serializer = clazz.kotlin.serializer()
2. 检查插件依赖声明
你的自定义Gradle插件中,kotlinx-serialization相关依赖要声明为compileOnly,不要打包进插件JAR:
// 插件项目的build.gradle.kts配置 dependencies { compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core:1.3.0") // 和目标项目使用的版本对齐即可 // 不要用implementation,否则会和目标项目的序列化依赖产生版本冲突 }
3. 确认编译输出路径已包含
你已经配置了任务依赖Kotlin编译步骤,还要确认上面构造类加载器时,已经包含了Kotlin编译任务的输出目录(默认路径为build/classes/kotlin/main),该目录下存放了编译器生成的序列化器类。
内容的提问来源于stack exchange,提问作者YYJo
相关产品推荐
相关产品推荐

