确认 Java 与编译依赖
从本章开始,教程假定您已掌握基础 Java 知识。 本章将已有源码整理为独立工程,编译后通过 JAR 交给游戏加载。本节配置 JDK 与游戏 API 依赖,随后再迁移源码、配置 Gradle,完成构建与加载。
本节预期阅读时间:~8 分钟。
本节预期操作时间:~10 分钟。
学习目标
完成后,您将能够:
- 为工程选择 JDK 17,并说明 Java 17 字节码目标的作用;
- 选择 IDE 的项目 SDK 与语言级别;
- 说明 classpath 中游戏 JAR 的编译职责;
- 将游戏依赖作为 compileOnly 配置。
前置知识
为工程选择 JDK
游戏使用 Java 17。本工程相应采用 JDK 17,生成的字节码目标也固定为 17。
游戏附带的 JRE 负责运行程序。编译源码还需要 javac,检查和打包产物还会用到 jar,这些开发工具由 JDK 提供。安装 JDK 17 后,将 IDE 的 Project SDK 指向这份安装,语言级别也设为 17。
本机可以同时安装多个 JDK,IDE 的 SDK 选项与终端的 PATH 也可以指向不同位置。将 IDE 与命令行的编译工具都配置为 JDK 17。 核对终端 java、javac 的版本和实际路径,确认它们使用预期的安装。
后面配置 Gradle 时还有两个相关设置:toolchain 选择编译器,release 指定产物的目标 Java 版本。运行 Gradle 自身的 JDK 则要满足所用 Gradle 版本的要求。它们都涉及 Java,但修改其中一项并不会替您完成其余设置。
编译成功仍可能加载失败
高版本编译器可以生成游戏无法运行的 class。目标版本过高时,错误会在游戏加载阶段表现为 UnsupportedClassVersionError。本工程将 release 固定为 17,编译环境与产物目标分别核对。
让编译器找到游戏 API
打开一份现有效果类,其中的 com.fs.starfarer.api 类型来自游戏。编译器要检查这些类型及其方法,就需要取得游戏已经编译好的类。把 Starsector/starsector-core/ 下的 *.jar 加入工程 classpath,便是提供这组编译依赖。
classpath 指定查找类的目录和 JAR。配置完成后,IDE 应当能够解析源码中的游戏类型;若依然报找不到类,核对的对象就是实际游戏目录及其中的核心 JAR。
为了阅读接口与注释,还可以给这组依赖附加 Starsector/starsector-core/starfarer.api.zip。这样从代码跳转时能够进入公开 API 源码。源码附件提供阅读内容,核心 JAR 提供编译所需的类。 仅附加源码,并没有完成编译依赖配置。
决定 MOD 要打包哪些类
编译需要游戏 JAR,运行 MOD 时游戏也已经提供了这些类。因此我们的产物保存自己编写的代码即可。后面的 Gradle 配置采用 compileOnly:核心 JAR 参与编译,普通 Java 插件的 jar 任务则打包当前工程的输出。
这项区别在自行配置打包任务时尤其重要。若任务把依赖 JAR 一并合入产物,游戏类也可能被复制进去。核对这种任务时,检查它实际收集了哪些输入,继续让游戏运行环境提供核心类。
至此,游戏目录、JDK 与 API 依赖已经确定。下一节整理源码位置,[C6-S3] 再将源码目录、依赖和目标版本写进构建文件;同一套配置随后用于反复构建。
验证方案
- 在 IDE 选择 JDK 17,将工程语言级别设为 17。
- 核对终端
java和javac版本,确认使用的是已配置的 JDK 17。 - 将核心目录 JAR 加入工程编译依赖,附加公开 API 源码。
- 从一处已有 API 引用跳转,确认 IDE 能够定位类型、方法与注释。
预期结果:
- IDE 与命令行使用 JDK 17,工程语言级别设为 17。
- IDE 可以解析已有游戏类,核心 JAR 进入编译 classpath。
- API 源码可用于查看方法与注释。
- MOD 产物职责为自己的类,游戏依赖按运行环境提供。
故障分析
加载时报 UnsupportedClassVersionError:产物目标高于游戏支持版本。
- 解决方案:将编译目标 release 设为 17,使用对应工具链重新构建。
IDE 或编译器找不到 API 类:核心 JAR 未进入 classpath,或路径指向不同目录。
- 解决方案:核对 starsector-core 路径和编译依赖,刷新工程。
终端工具版本与 IDE 不同:PATH、SDK 和 Gradle 工具链各自选择了不同安装。
- 解决方案:按工具的实际路径核对,编译固定为 JDK 17。
JAR 包含游戏类:自定义打包过程合并了核心依赖。
- 解决方案:使用工程输出作为产物输入,游戏 JAR 采用 compileOnly。
总结
本节准备的是源码离开游戏之后的编译条件:JDK 提供工具,核心 JAR 提供游戏类型,字节码目标保证产物能由当前运行时加载。源码附件让 API 便于阅读,这些条件随后都会落实到工程配置中。
现有系统、插件和生成器仍使用原来的完整类名。接下来改变源码的保存与构建方式,已经建立的数据引用继续沿用。
建议参考项
Starsector/starsector-core/*.jar:核心编译依赖。Starsector/starsector-core/starfarer.api.zip:公开 API 源码附件。