调试

日志(Log)是调试服务器中不可或缺的东西。本文将通过几个基本的日志示例来解释“当你遇到一样的问题时,可以做什么”。如果你是来找“哪些 Mod 和 SpongeForge 装一起会出问题”的,我们建议你先阅读这个:Mod 兼容

待办事项列表

当你遇到崩溃或警告,首先确认你 SpongeForge 或 SpongeVanilla 配置正确。这里有一个能帮到你的排查清单。如果你不知道如何获取所需的信息,请查看 日志文件 页面。它解释了如何从你的日志文件获取所需的答案。

Sponge 是否运行在 Java 8 上?

Sponge 需要 Java 8 ,使用 Java 7 或更旧的版本会导致崩溃。

安装了其他 Coremods 吗?

部分 Coremod 通过更改 Forge 或 Minecraft 方式使 SpongeForge 无法正常运行。若您安装了 coremod 且 Sponge 意外退出,请尝试移除它们并重新测试。请在`GitHub <https://github.com/SpongePowered/SpongeForge/issues>`__ 上汇报任何不兼容的 Coremod。这将允许工作人员尽快解决问题。

你使用的每一个插件都是针对 Sponge 构建的吗?

SpongeAPI 有时会改变。当你在新版 Sponge 上使用旧版本插件并遇到了崩溃时,请尝试降级 Sponge,或与插件作者联系获得更新的插件。如果你在旧的 Sponge 版本上使用新版本插件发生崩溃时,首先尝试更新 Sponge。如果这不能解决问题,请联系插件作者。

分离一个错误的插件

如果问题仍然存在,删除所有插件并重新逐一添加,并且每次都重启服务端。

如果你仍然不确定为什么崩溃,看一看你的 crashlog。下面列出了一些常见的崩溃和解决办法。

备注

若您遇到错误,创建一个备份通常是个好想法,然后请尝试重新产生错误并使用移除模组的方式缩小范围。只有在这时您才应汇报错误。若错误在缺少 Sponge 插件时发生则请移除 SpongeForge。若错误仍存在且与 Sponge 无关,则首先请向对自己所写代码熟悉的模组作者汇报。您一直可以联系我们咨询问题。更多详情请参见报告问题

一般警告

常见的错误和 bug 来源是 SpongeForge 与 Sponge 之间或 SpongeForge 和插件之间的版本不匹配。首先我们来看看在Forge给出的一般警告︰

WARNING: coremods are present:
   SpongeForge (sponge-1.8-1521-2.1DEV-750.jar)
Contact their authors BEFORE contacting forge

这不是一个 bug 或错误,它只是Forge告诉你,Coremod (在这里︰ SpongeForge) 安装。Forge建议您在联系他们之前先联系Sponge开发人员。Don’t Worry。

常见异常

这里有一些常见的异常和异常发生的原因。

备注

如果你遇到崩溃、 错误或任何这里没有提及的问题,请前往 Sponge 论坛或者我们的 GitHub 反馈。这样还能帮助碰到同样问题的人。

SpongeForge 与 Forge 不匹配

[12:59:21] [main/ERROR] [mixin/]: @Mixin target net.minecraftforge.event.world.BlockEvent$NeighborNotifyEvent was not found mixins.forge.core.json:event.block.MixinEventNotifyNeighborBlock

这是一些常见的SpongeForge与Forge版本不匹配的崩溃,始终保持版本匹配!如果你不确定需要Forge的那个版本,或者你已经有了一个不可改变版本的 SpongeForge,看这里:读懂文件名

其它常见错误

Caused by: java.lang.ClassNotFoundException: org.spongepowered.api.event.state.ServerStartedEvent
Caused by: java.lang.NullPointerException

第一个错误是 Class is missing ,第二个错误是 NullPointer Exception 表明你安装的插件缺少依赖元素,这通常发生在插件版本和Sponge版本不匹配的情况下

java.lang.AbstractMethodError: net.minecraft.entity.player.EntityPlayerMP.getTabList()Lorg/spongepowered/api/entity/living/player/tab/TabList;
at (...)

当一个插件试图调用尚未实现的方法时发生了 AbstractMethodError 。请检查是否你运行当前最新的 Sponge ,若不是,请更新。如果问题仍然存在,要么报告、 论坛或 IRC 上官方的 Issuetracker 。您也可以请求执行缺少的功能.。

[Server thread/INFO]: Starting minecraft server version 1.8
[Server thread/ERROR]: Encountered an unexpected exception
java.lang.NoClassDefFoundError: org/spongepowered/api/event/game/state/GameStartingServerEvent

备注

读更多更全的崩溃报告?在这里 SpongeForge 575 crashlog with a plugin built against build 750

NoClassDefFoundError 表示这个 Class 不存在于 classpath 中,一般发生在 API 调整或者重构后,你更新了 Sponge 但你用的插件没有更新,或者反过来。请务必让插件版本和 Sponge 版本保持匹配!你可以去问插件作者啥时候更新,也可以自己升级或降级 SpongeForge 或 SpongeVanilla 来解决。

运行时异常

在模组服务器上通常会发生两种错误:

  • 插件内部错误,如命令执行时的 NullPointerExceptions。这些错误使用标准 Java 处理器进行记录。

  • 世界或实体周期错误。Sponge 将打印出更多结构化错误以提供尽可能多的信息。

在我们研究造成异常的原因前,请确保您阅读了完整错误汇报。有时错误已在错误汇报本身(上方或下方几行)中被诠释;有时它会在启动时显示。

下列栈跟踪显示了此特殊处理的示例(除了行时间前缀及严重度):

/******************************************************************************************************************************/
/*                                           Exception occurred during a PhaseState                                           */
/******************************************************************************************************************************/
/* Sponge's tracking system makes a best effort to not throw exceptions randomly                                              */
/* but sometimes it is inevitable. In most cases, something else triggered this                                               */
/* exception and Sponge prevented a crash by catching it. The following stacktrace                                            */
/* can be used to help pinpoint the cause.                                                                                    */
/******************************************************************************************************************************/
/* The PhaseState having an exception: EntityTickPhase                                                                        */
/* The PhaseContext:                                                                                                          */
/*     - Owner: EntityPlayerMP['SomePlayer'/270, l='world', x=119,62, y=82,00, z=260,21]                                      */
/*     - Source: EntityCreeper['Creeper'/346, l='world', x=119,50, y=82,00, z=258,50]                                         */
/*     - CapturedBlockPosition: CaptureBlockPos{pos=null, world=Optional.empty}                                               */
/* org.spongepowered.asm.util.PrettyPrinter@56ec63ef                                                                          */
/******************************************************************************************************************************/
/* StackTrace:                                                                                                                */
/* java.lang.NullPointerException: null                                                                                       */
/*     net.minecraft.util.math.BlockPos.<init>(SourceFile:41)                                                                 */
/*     net.minecraft.pathfinding.PathNavigateGround.func_75494_a(SourceFile:73)                                               */
/*     net.minecraft.pathfinding.PathNavigate.func_75497_a(SourceFile:147)                                                    */
/*     com.example.extendedaiplugin.BrokenAITask.start(BrokenAITask.java:58)                                                  */
/*     org.spongepowered.common.entity.ai.SpongeEntityAICommonSuperclass.func_75249_e(SpongeEntityAICommonSuperclass.java:43) */
/*     net.minecraft.entity.ai.EntityAITasks.func_75774_a(SourceFile:102)                                                     */
/*     net.minecraft.entity.EntityLiving.func_70626_be(EntityLiving.java:763)                                                 */
/*     net.minecraft.entity.EntityLivingBase.func_70636_d(EntityLivingBase.java:2350)                                         */
/*     net.minecraft.entity.EntityLiving.func_70636_d(EntityLiving.java:577)                                                  */
/*     net.minecraft.entity.monster.EntityMob.func_70636_d(EntityMob.java:45)                                                 */
/*     net.minecraft.entity.EntityLivingBase.func_70071_h_(EntityLivingBase.java:2170)                                        */
/*     net.minecraft.entity.EntityLiving.func_70071_h_(EntityLiving.java:295)                                                 */
/*     net.minecraft.entity.monster.EntityMob.func_70071_h_(EntityMob.java:50)                                                */
/*     net.minecraft.entity.monster.EntityCreeper.func_70071_h_(EntityCreeper.java:172)                                       */
/*     org.spongepowered.common.event.tracking.TrackingUtil.tickEntity(TrackingUtil.java:160)                                 */
/*     net.minecraft.world.WorldServer.redirect$onCallEntityUpdate$zlo000(WorldServer.java:2986)                              */
/*     net.minecraft.world.World.func_72866_a(World.java:4154)                                                                */
/*     net.minecraft.world.WorldServer.func_72866_a(WorldServer.java:832)                                                     */
/*     net.minecraft.world.World.func_72870_g(World.java:1952)                                                                */
/*     net.minecraft.world.World.func_72939_s(World.java:6596)                                                                */
/*     net.minecraft.world.WorldServer.func_72939_s(WorldServer.java:2300)                                                    */
/*     net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:767)                                            */
/*     net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:396)                                  */
/*     net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:668)                                            */
/*     net.minecraft.server.MinecraftServer.run(MinecraftServer.java:526)                                                     */
/*     java.lang.Thread.run(Unknown Source)                                                                                   */
/*  Phases Remaining:                                                                                                         */
/*                                                                                                                            */
/* Minecraft : 1.12.2                                                                                                         */
/* SpongeAPI : 7.1.0-SNAPSHOT-7105dfc                                                                                         */
/* SpongeForge : 1.12.2-2705-7.1.0-BETA-3361                                                                                  */
/* Minecraft Forge : 14.23.4.2705                                                                                             */
/******************************************************************************************************************************/

此栈跟踪包含最为重要的版本号和服务器所处阶段信息。此例中,服务器在 EntityTickPhase 阶段抛出了 NullPointerException。此时,查看哪些插件包含在了崩溃中是极为重要的。这需要您匹配包名与模组名;查看 Caused by 日志块也许对您有帮助。

  • java 类在搜索错误时可被忽略。

  • net.minecraft 是原版 Minecraft 代码。若只存在此成分,则有可能是 Minecraft 错误或 Coremod 错误。

  • org.spongepowered 来自 Sponge 本身,仅包含此日志和 Minecraft 包时通常意味着 Sponge 错误(或存在其他 Coremod)。

  • 其他类需要被人工关联至模组。此例中存在入口点 com.example.extendedaiplugin;Java 项目通常以 组编号.组编号.作品编号 的形式命名。组名通常是反过来的域名;此例中则是 example.com,随后则是项目名即作品名。欲知 Java 包命名的更多详情您可参考`官方文档 <https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.2>`_。此插件可能名为 extendedaiplugin,若您有疑问,在网上进行搜索完整包名可能对您有帮助。

警告

当 Coremod 存在时务必小心。这可意味着虽然服务器汇报 Minecraft 类存在问题,但不意味着其执行的代码是 Minecraft 源码的一部分且此段代码可为第三方添加。您可以查看已加载的 Coremod 日志并通过一一移除的方法找到原因。请注意有些问题仅可能在同时加载特定 Coremod 时出现。