你下了一个 1.16.5 的 Forge 服,点启动,终端刷出一片红字,最上面一行是 UnsupportedClassVersionError,后面跟着 class file version 61.0。你上网搜,有人说“装 Java 8”,可你在运行环境里翻了一遍——Termux 只有 11、17、21、25,根本没有 8。
这不是应用缺功能,而是 Java 有个硬规则:每个游戏版本要求的 Java 版本不一样,而不同来源能提供的 Java 版本也不一样。 两条约束撞在一起,就会出现“知道该装什么、却不知道去哪装”的僵局。
这一页把三条线拆开:游戏版本怎么编号、每个版本要哪个 Java、Minexa 在什么情况下会自动帮你换、什么情况下只能你自己动手。
三个版本别混:游戏版本(你和朋友的客户端)、核心版本(下载页给的)、Java 版本(运行环境提供的)。
对应关系记四档:1.16 用 8、1.17 用 17、1.21 用 21,26.x 用 25。
Minexa 的自动匹配只升版本、不换来源;来源没有目标版本时它只会报错。
Java 8 只有 PRoot focal 提供,Termux 和 Pojav 都没有。
报错里
class file version 61.0对应 Java 17,不是“版本 61”。
先分清三个“版本”#
新手最容易把三个东西混成一个:
| 版本 | 例子 | 谁决定 |
|---|---|---|
| 游戏版本 | 1.21.4、26.x | 你和朋友的客户端 |
| 核心版本 | Paper 的 build 号、Forge 的 loader 版本 | 下载页提供 |
| Java 版本 | 8 / 11 / 17 / 21 / 25 | 运行环境提供 |
Java 在这里指 JVM(Java 虚拟机,可以理解成一台“虚拟电脑”,.jar 程序在它里面跑)。服务端是个 jar 包,所以必须先有一台合适的虚拟电脑;版本低了,jar 根本装不进去。
三者要对齐,顺序是:客户端和服务端的游戏版本必须一致(1.21.4 的客户端进不了 1.21.1 的服),核心要支持这个游戏版本,Java 要满足核心的要求。三者里只有 Java 是“可以往上加”的,游戏版本不能差半档。挑哪个游戏版本,见 选版本、升级与降级。
一张表:游戏版本对应哪个 Java#
| 游戏版本 | 需要 Java | 说明 |
|---|---|---|
| 1.16.x 及更老(≤ 1.16) | 8 | 老版本 Forge 多半只认 8,11 有时能凑合 |
| 1.17 – 1.20.6 | 17 | 1.20.5 / 1.20.6 属于临界版本,见下面的提醒 |
| 1.21 – 1.21.x | 21 | 目前最常见的组合 |
| 26.x 及以后 | 25 | 新编号体系,不再写成 1.x |
它给的是最低要求的大致对应,最终以核心官方文档为准:不同核心、不同模组可能把要求抬高半档。用法是:按表选一档 → 启动看是否报 class file version 或 requires Java N → 报了就往上加一档。
两个细节单独说:
26.x 是新编号。Minecraft 不再只写
1.x,出现了主版本号 26 这种写法;Minexa 按「主版本号 ≥ 26」识别,推荐 Java 25,以核心文档为准。1.20.5 / 1.20.6 是临界点。不同核心对这两个版本的要求不完全一致,代码里也存在按 17 和按 21 处理两种判断。遇到它报
class file version 65.0,直接调到 Java 21 再试。
Minexa 会自动选,但只有两条边界#
启动前,应用会读当前核心的游戏版本,算出推荐 Java,然后和你选中的版本比较。规则是:
主版本号 ≥ 26 → 25;
1.21 及以上 → 21;
1.17 – 1.20.6 → 17;
1.16 及更老 → 8;
Forge 且游戏版本 ≤ 1.16 → 在 8 和 11 里挑,优先 8;
Allay → 强制 21 及以上;
PowerNukkitX 和「未知」不参与这套匹配。
它只做两件事,边界也必须记住:
边界一:只升不降。 Java 的顺序是 8 < 11 < 17 < 21 < 25。只有你当前选的版本低于推荐值时才会自动切换;你手动选了更高版本,它不会把你降回去。
边界二:只换版本,不换来源。 如果来源根本不提供这个版本,应用不会偷偷换来源,而是报错让你决定——来源是你选的,应用不会替你改。
自动切换会写进配置(下次启动沿用),终端里会留一行类似“1.16.5 需要 Java 8 及以上(当前选择 Java 17),已自动切换”的记录。所以“我明明选了自动,怎么还报错”的答案通常是:你要的那个版本,这个来源压根没有。
Java 8 为什么只有 PRoot focal 有#
这是新手最容易被卡住的地方。四个来源实际能装的版本是这样的:
| 来源 | 可装版本 | 什么时候用它 |
|---|---|---|
| Termux JDK | 11 / 17 / 21 / 25 | 默认最省事,1.17 以上的首选 |
| Pojav JRE(FCL) | 17 / 21 / 25 | Android 原生 JRE,自带 IPv6 支持 |
| PRoot · Ubuntu 20.04 (focal) | 8 / 11 / 17 | 需要 Java 8 时唯一的选择 |
| PRoot · Ubuntu 22.04 (jammy) | 11 / 17 / 21 | 需要标准 glibc 环境的软件 |
| PHP | PocketMine 专用 | 只给 PocketMine-MP 用 |
三个坑记牢:
Termux 和 FCL 没有 Java 8。 不是没装,是压根不提供。1.16 及更老的服在 Termux 下启动,一定会看到“当前来源不提供 Java 8”。
PRoot 容器没有 Java 25。 两个发行版最高都只到 21,想跑 26.x 就得回到 Termux 或 FCL。
换发行版不会删掉已装的 Java。 从 jammy 切到 focal 只是多出一批可选版本,之前装的 17 还在。
为什么 Java 8 只能待在容器里?因为它的 Linux 构建依赖 glibc(GNU C 运行库),而 Android 用的是 bionic(安卓的 C 运行库)。Termux 直接在 Android 上跑,只能用 bionic 适配的构建;PRoot 里是完整 Ubuntu,有标准 glibc,老 JDK 才装得上。
启动服务端卡右上角齿轮 →「运行环境」选「PRoot Linux 容器」→「Linux 发行版」选「Ubuntu 20.04 (focal)」→ 在容器内的 Java 版本里选 Java 8 并安装。发行版选项排在 Java 版本前面,因为它决定下面能列出哪些版本。
这些改动只影响下一次启动,不会打断正在运行的服务端。完整的运行环境界面说明见 运行环境与依赖管理。
怎么确认现在用的是哪个 Java#
按可靠程度从高到低:
启动设置抽屉里选中的那一份——这才是真正会用来启动的 Java。抽屉里也写着“改动只影响下一次启动”。
概览「启动服务端」卡的「当前运行环境」——显示成
来源 · 版本,例如Termux · Java 21。运行环境与依赖管理页——每个版本后面标「已安装」或「未安装」,能看出这个来源到底有没有装。
终端里敲
java -version——只能当参考。shell 和服务端启动用的不是同一套 PATH,找不到不代表没装,显示出来也不一定是启动时用的那份。
判断用哪份 Java,以启动设置抽屉为准,因为启动命令里的路径是应用自己拼的,跟你手动敲命令时找到的不是一回事。
报错对照:三类典型信息#
| 日志里出现 | 含义 | 怎么做 |
|---|---|---|
UnsupportedClassVersionError + class file version 61.0 | 用低版本 Java 跑了高版本编译的 jar。52=Java 8,55=11,61=17,65=21,69=25 | 把 Java 提到对应版本或更高 |
requires Java 21 / Java 21 or higher | 核心自己检测到版本不够,直接拒绝启动 | 同上,装到要求的那一档 |
当前来源「Termux」不提供 Java 8 | 来源里没有这个版本,应用拒绝偷偷换来源 | 改用 PRoot focal,或把游戏版本提到 1.17+ |
libjvm 段错误 / 启动即崩,无 Java 版本提示 | 用 bionic 版 Java 11 跑老 Forge,兼容性问题 | 换 PRoot focal 的 Java 8 |
第一条最常被误读:61 不是“版本 61”,它对应的是 Java 17。看懂这个数字,就不用再猜缺哪个 Java 了。
只有 1.16 及更老的版本才需要 Java 8。给 1.21 的服装 Java 8,会直接抛 UnsupportedClassVersionError。
启动失败时先看报错里有没有 class file version 或 requires Java,没有就去查核心、模组、端口,别拿 Java 版本当万能解。更多现象对号入座见 启动失败:卡住、闪退、迟迟不出 Done。
升级游戏版本时,按这个顺序动#
备份世界。整服备份或至少导出
world/三个目录,见 备份策略与恢复演练。确认客户端版本。朋友那边升到哪个版本,服务端就跟到哪个,别只升一边。
下载同类型的新核心。Paper 换 Paper,Fabric 换 Fabric;跨类型迁移等于重做。
先处理插件/模组。它们比核心更挑剔,先升到支持新版本的版本,或者先移出目录。
按表确认 Java。1.17 起是 17,1.21 起是 21,26.x 是 25;不够就加。
启动并等
Done。新版本世界要做数据升级,第一次比平时慢,别急着杀掉。出问题就回滚。旧核心 + 旧存档 + 旧 Java,三样一起退回去。
内存分配和 Java 版本是两件独立的事:前者决定能不能跑,后者决定跑得稳不稳。堆内存怎么给见 内存分配:给服务器多少 RAM 才够。
概览「当前运行环境」显示成
来源 · 版本,你能读出来是哪份 Java。终端里没有
UnsupportedClassVersionError,也没有“当前来源不提供 Java X”这类提示。如果跑 1.16 及更老的核心,来源是 PRoot + Ubuntu 20.04 (focal),Java 8 已安装。
如果跑 26.x,来源是 Termux 或 Pojav,Java 25 已安装,没有硬用 PRoot。
改完运行环境后,是重新启动服务端验证的,不是看界面变绿就结束。
下一步#
想弄清运行环境、安装与切换的完整界面:运行环境与依赖管理(Java / PHP / PRoot)
在选择 1.21 的哪一个小版本:选版本、升级与降级
已经报错卡住:启动失败:卡住、闪退、迟迟不出 Done