Skip to content

fix(common-env): 修复多插件不同协程版本导致 NoClassDefFoundError#692

Closed
zhibeigg wants to merge 1 commit into
TabooLib:dev/6.2.3from
zhibeigg:fix/coroutines-version-conflict
Closed

fix(common-env): 修复多插件不同协程版本导致 NoClassDefFoundError#692
zhibeigg wants to merge 1 commit into
TabooLib:dev/6.2.3from
zhibeigg:fix/coroutines-version-conflict

Conversation

@zhibeigg
Copy link
Copy Markdown
Contributor

问题描述

当服务器上多个 TabooLib 插件使用不同版本的 Kotlin Coroutines 时(例如插件 A 使用 1.10.1,插件 B 使用 1.9.0),后加载的插件会抛出 NoClassDefFoundError

java.lang.NoClassDefFoundError: kotlin2120x/coroutines1101/CoroutineExceptionHandler

单独加载任一插件均正常,仅在多插件共存且协程版本不同时触发。

根因分析

AetherResolver.inject() 的去重逻辑中,id 仅包含依赖的 group/nameIS_ISOLATED_MODE,不包含 relocate 规则信息:

String id = file.getParentFile().getParentFile().getPath()
        + ":" + PrimitiveSettings.IS_ISOLATED_MODE;

这导致:

  1. 插件 A 先加载 kotlinx-coroutines-core-jvm:1.10.1,relocate 为 kotlin2120x.coroutines1101.*,注入成功
  2. 插件 B 后加载 kotlinx-coroutines-core-jvm:1.9.0,由于 group/name 相同被去重跳过
  3. 但插件 B 的模块代码已被 relocate 为引用 kotlin2120x.coroutines190.*
  4. 实际只有 kotlin2120x.coroutines1101.* 被加载 → NoClassDefFoundError

修复方案

在去重 id 中加入 relocation 规则的 hashCode,使不同 relocate 规则的同一依赖可以分别加载,而相同 relocate 规则的同一依赖仍然会被正确去重:

String id = file.getParentFile().getParentFile().getPath()
        + ":" + PrimitiveSettings.IS_ISOLATED_MODE
        + ":" + (relocation != null ? relocation.hashCode() : 0);

影响范围

  • 仅修改 AetherResolver.java 一个文件
  • 不影响隔离模式和 Legacy 依赖加载路径
  • 向后兼容:无 relocate 规则时 hashCode 为 0,行为与原逻辑一致

AetherResolver.inject() 的去重 id 仅包含依赖的 group/name,
不包含 relocate 规则信息。当多个 TabooLib 插件使用不同版本的
Kotlin Coroutines 时,先加载的插件注册了依赖 id,后加载的插件
因去重被跳过,但其模块代码已被 relocate 成引用不同版本的包名,
导致 NoClassDefFoundError。

在去重 id 中加入 relocation 规则的 hashCode,使不同 relocate
规则的同一依赖可以分别加载。
@zhibeigg zhibeigg closed this Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant