Jar-in-Jar 嵌套 jar
基本信息
| 属性 | 值 |
|---|---|
| 触发字段 | manifest 的 Jar-In-Jar 属性,CSV 形式相对路径 |
| 抽取类 | JarUtil.getNestedJar |
| 抽取目录 | <mc>/nestedmods/ (由 CoreModManagerV2.setupNestedModDir 创建) |
| 去重机制 | SHA-256 → 文件名 <basename>-<sha256>.jar |
| 重新抽取条件 | 同 hash 文件不存在 |
Jar-in-Jar 是 Forge 1.7.10 时代引入但并未实际实现的"嵌套 mod"机制——JarJar 接管了这一流程,让 mod 开发者能把多个 jar 嵌入到自己的分发 jar 内,按嵌套依赖加载。
读取位置
- Coremod 阶段:
CoreModManagerV2.loadCommandLineCoremods对命令行通过-Dfml.coreMods.load=注入的每个 coremod 检查其 Jar-in-Jar - Mod 发现阶段:
ParallellModDiscoverer.ModScanTask.computeJarFile检测外层 jar 的 manifest;存在Jar-In-Jar时通过JarUtil.checkNestedJars抽取并并行扫描每个嵌套 jar - 校验阶段:
JarUtil.examineJarCandidate内if(coremodPass)分支设置nestedModcandidates
抽取算法
JarUtil.getNestedJar(jarFile, nestedJarPath, targetDir):
- 用
jar.getJarEntry(nestedJarPath)取 entry;找不到则打 ERROR 跳过 - 套
RewindableModInputStream包裹jar.getInputStream(entry),支持读完 SHA-256 后倒回再写盘 DigestUtils.sha256Hex计算 64 字符 hex- 同步块内构造
outputJarFile = new File(targetDir, baseName + "-" + hash + ".jar") - 若不存在:
is.rewind()- 1 KB 缓冲循环写出
- 返回
record NestedJar(File file, String sourceFilename, String hash)
JarUtil.checkNestedJars(jar):
manifest.getMainAttributes().getValue("Jar-In-Jar")为空 → 返回空列表- 用
HashSet去重 CSV 路径(防止 manifest 写重) - 调
getNestedJar把每条记录抽取到CoreModManagerV2.getNestedDir()(即<mc>/nestedmods/)
并行机制
ParallellModDiscoverer.ModScanTask.computeJarFile:
- 遍历
modCandidate.getNestedJars()(即NestedJar列表) - 用
ConcurrentHashMap<String, ModScanTask> jijDedupMap(key =nestedJar.hash())避免同一 hash 重复 fork - 第一个 task 不 fork,留给当前线程;其余
task.fork()异步执行 tasks收集完成后,最末尾localTask.invoke()阻塞等首任务,递归把结果装入modCandidate.setNestedModcandidates(nestedMods)nestedModInitDatas.add(new NestedModInitData(tasks, nestedMods))统一收集 future,外层discoverMods()二次future.get(timeout, ...)收割
输出命名
| 输入 entry 名 | 输出文件名 |
|---|---|
libs/optional-1.2.3.jar |
optional-<sha256>.jar |
mymod.jar |
mymod-<sha256>.jar |
抽取目录 <mc>/nestedmods/:
- 在
CoreModManagerV2.handleLaunch中setupNestedModDir创建 - 路径规范化用
getCanonicalFile() - 已存在但不是目录则抛 RuntimeException
相关条目
- JarUtil 嵌套抽取与版本识别 -
getNestedJar/checkNestedJars实现 - CoreModManagerV2 -
setupNestedModDir/loadCommandLineCoremods - 并行 mod 发现 -
ParallellModDiscoverer调度嵌套 jar 扫描 - ModCandidateV2 数据模型 -
setNestedJars/setNestedModcandidates字段