弱鸡绿毛怪
本帖最后由 MagicLocyDragon 于 2019-5-3 08:01 编辑

零基础如何看插件报错

· 前言
本教程只是讲了一些基础的报错怎么看,复杂的报错得让开发者去搞
本教程面向不会看报错不知道报错在讲什么 的服主,若有讲的不妥,该教程只是面向服主

来QQ交流群讨论: 546818810

粗体字是重点
当然 如果你看了这篇文章还是不知道怎么看 可以在下面贴出你的报错,有空会帮忙看下
看得快的话,一首歌的时间就能看完了

最后希望各位新手小白早日变成大佬

1. 插件的报错是什么
通俗来讲,就是插件运行异常的提示。但是报错通常有一大段,密密麻麻的,当然开发者也不会一条一条去看,主要是看里面的关键内容,比如下面这个例子
[19:56:49] [Server thread/WARN]: java.lang.ClassNotFoundException: net.minecraft.server.v1_8_R3.EntityShulker
[19:56:49] [Server thread/WARN]:         at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:91)
[19:56:49] [Server thread/WARN]:         at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:86)
[19:56:49] [Server thread/WARN]:         at java.lang.ClassLoader.loadClass(Unknown Source)
[19:56:49] [Server thread/WARN]:         at java.lang.ClassLoader.loadClass(Unknown Source)
[19:56:49] [Server thread/WARN]:         at java.lang.Class.forName0(Native Method)
[19:56:49] [Server thread/WARN]:         at java.lang.Class.forName(Unknown Source)
[19:56:49] [Server thread/WARN]:         at me.libraryaddict.disguise.utilities.ReflectionManager.getNmsClass(ReflectionManager.java:470)
[19:56:49] [Server thread/WARN]:         at me.libraryaddict.disguise.LibsDisguises.onEnable(LibsDisguises.java:79)

[19:56:49] [Server thread/WARN]:         at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321)
[19:56:49] [Server thread/WARN]:         at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340)
[19:56:49] [Server thread/WARN]:         at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405)
[19:56:49] [Server thread/WARN]:         at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugin(CraftServer.java:357)
[19:56:49] [Server thread/WARN]:         at org.bukkit.craftbukkit.v1_8_R3.CraftServer.enablePlugins(CraftServer.java:317)
[19:56:49] [Server thread/WARN]:         at net.minecraft.server.v1_8_R3.MinecraftServer.s(MinecraftServer.java:408)
[19:56:49] [Server thread/WARN]:         at net.minecraft.server.v1_8_R3.MinecraftServer.k(MinecraftServer.java:372)
[19:56:49] [Server thread/WARN]:         at net.minecraft.server.v1_8_R3.MinecraftServer.a(MinecraftServer.java:327)
[19:56:49] [Server thread/WARN]:         at net.minecraft.server.v1_8_R3.DedicatedServer.init(DedicatedServer.java:267)
[19:56:49] [Server thread/WARN]:         at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:561)
[19:56:49] [Server thread/WARN]:         at java.lang.Thread.run(Unknown Source)

这就是一个报错,而这里有一大段,真正对研究问题有用的也就是粗体的那几段。
· 那么,哪些报错是有价值的呢?哪些是可以不用看的呢?
我们在这里只讨论 插件报错 的情况,暂时不讨论 核心炸了 的情况

2. 哪几行报错是有价值的?
很多小白服主跑到大佬们的QQ群,把所有报错截下来发送出去,不仅刷屏还烦人心,其实大多数情况下都是可以自己解决的。建议大家以截图的方式发送报错。

首先我们要会看报错,我们必须要有以下三个java基础概念,但是为了能听懂,我可能会打几个不太恰当的比喻

概念一: 类(Class) —— 类我们可以看作一颗零件,每个插件是由很多个零件组成的,服务端也是有很多个零件组成的,我们甚至还可以把java本身理解成一大坨零件若其中一个零件坏了(报错),会引起一系列连锁反应

概念二: 包(Package,我们通常能在异常中的 at xxxxxxxxx 可以找到) —— 包指明了类所在的位置,即每个零件在哪。有良好开发习惯的开发者通常会在包名中出现或暗示自己的插件名,便于看报错
概念三: 异常(Exception) —— 它通常是 XXXXException:原因 这代表这颗螺丝出错的原因,这很关键

1.包和类
包和类在报错中是一起出现的,格式:  包名.类名.方法名   ——(方法名是什么无需知道)
举个例子:

org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugin
这一条信息中, 包名是 org.bukkit.craftbukkit.v1_8_R3
类名是CraftServer
方法名是loadPlugin

再举个例子:
me.libraryaddict.disguise.utilities.ReflectionManager.getNmsClass
这一条消息中 me.libraryaddict.disguise.utilities是包名
ReflectionManager是类名
getNmsClass是方法名

那为什么只有一个报错,但是报错信息上出现了很多这样的信息呢?我们可以把它理解成为其中一个类(即一个零件)出了故障,引起了连锁反应,牵涉到其他的类。

2.异常
异常是以 异常名:原因出现的 举个例子:
java.lang.ClassNotFoundException: net.minecraft.server.v1_8_R3.EntityShulker

这里的异常名就是ClassNotFoundException(或叫java.lang.ClassNotFoundException也能理解)
原因(内容)是 net.minecraft.server.v1_8_R3.EntityShulker
其实异常名都是比较通俗易懂的,比如这个,我们拆开来就是
Class Not Found —— 意思是 找不到类
结合原因来看是 找不到net.minecraft.server.v1_8_R3.EntityShulker
这个类

3.如何选取有用的报错?
若仅是插件报错,
我们可以无视(也不能说是无视,你可以看看这些类里面或许也存在一些信息)以下几个包名:(下面的红字尤其重要)
① 以 java. / sun. / org.apache. 等开头的包名,比如
java.lang (这是java内部的类)
以 org.bukkit.craftbukkit.<服务端版本号> 或 net.minecraft.server.<服务端版本号> 开头的包名
(这是核心里的类)
③ EventException 下面的 直到 其他的Exception


抛开以上几个,我们剩下要看的就寥寥无几了
我们这里又要提到这个包名:
me.libraryaddict.disguise.utilities.ReflectionManager.getNmsClass
这个既不是 java内部的类 也不是 核心里的类 那么它十有89就是插件里的类了
我们根据包名中的关键字 disguise 能推测出,这大概是某个伪装插件 再翻一下插件列表 发现是LibDisguise

3. 异常常见的种类
1.NoClassDefFoundException或ClassNotFoundException
出现原因:缺少类 但是他会在后面指明你缺了哪个类
我们举个不同的例子,比如上面的

java.lang.ClassNotFoundException: net.minecraft.server.v1_8_R3.EntityShulker
·   这说明了我们缺少
net.minecraft.server.v1_8_R3.EntityShulker 这个类,如果你前面认真看了的话,你就知道这个是核心里的类,我们推理出 在通常情况下,不同的版本上 核心里面的类都是有点差异的,就是说,这个插件在你这个版本上的核心玩不起来,你可以试试: 换个核心 或者 换个插件版本

2.NoSuchMethodError
出现原因:找不到类里的方法,不过你无须知道方法是什么,你可以理解成方法是类里面的东西就行了
举个例子:

我们看出,这是核心里的某个类里的方法 插件想要使用这个方法 但是找不到
我们推出: 你的服务器可能不适合这个插件 或者 这个版本的插件不适合这个版本的服务器

再举个例子:

我们通过对类名的猜测,知道这既不是核心也不是java的类,那就是其他插件了
我们这里是 Vault 插件的锅 这里的因素就有很多了
可能:
Vault的版本太旧了,调用方法的插件调用了Vault插件新版本(即旧版本没有的方法),炸了
你服务器里压根没有Vault
Vault的版本太新了,移除了旧版本中冗杂的方法,而你的插件正好调用了
你的插件版本太旧了,试试换个新的

3.UnknownhostException/
HttpxxxException(之类名字中含有网络有关的异常)
出现原因:可能是插件在获取新版本信息或者在更新自己的时候,连接不上更新服务器。若你不用更新的话不管就行。

4.NullPointerException(空指针异常)
出现原因:这个报错很常见,正因为常见,所以范围很广泛,很难一言两语概括了
不过根据异常名,我们知道 这个异常 和 有关

举个例子吧:
可能你点击了一个空白的格子,而某个插件的开发者没做好,就造成了这个异常
还有可能是你空手右键,某个插件的开发者以为你手上拿了个东西,其实是空的,就造成这个异常

总之 这个异常三成是你自己的锅,七成是开发者的问题,毕竟开发者们也不是神,也会像小学生一样出点小问题(注: 某些插件版本不兼容也可能发生这个异常)
但是如果不影响服务器运作,可以找一个屏蔽插件不管他


5.其他异常
其实随便找个有底子的开发者都能看得懂大部分异常,但有一丁点可能,看得懂却不能解决(雾
异常的种类有很多,成千上万,每个开发者都可以制作专属的异常,在这里全部说清楚是不可能的。还是要求助百度问一下这个异常是什么的,但是我们还是可以从报错和百度翻译(别去翻译包名,没啥意义,翻译报错原因)猜出个大概,比如下面这个

IllegalStateException: Cannot make FireworkEffect without any color

这个都看得懂吧,看不懂的去百度2333

6.NoSuchFieldError
通常是版本不兼容或前置插件版本过旧或过新

4.实例
1.
如果你百度过,就知道这是访问网络时出的问题,但是为什么要访问网络呢?我们从最后一行的storage关键词看出,大概是同步玩家的数据?我们只能分析到这里,继续往下分析还需看源码

2.
这是一个找不到方法的报错,是getOnlinePlayers方法,而且是核心里的,我们基本可以推出是版本不符合了,事实上,这个方法是经常出问题的一个方法,因为bukkit的辣鸡开发(呸,导致这个方法高低版本是不同的
3.
由开发者良好的命名规范(不是每个插件都能这么看,这要看作者的开发素质),我们联系上面的关键字 "Http" 一眼看出这是在检查更新的时候没连上服务器报错,没必要不用管即可。(这个人报错没截全,报错种类原因都没有,我们只能通过包名推断

错误的发报错示范:

上面我们说,可以忽视EventException以下直到xxxException的内容,而这里只截了这一段,我们只能看出
EasyKitsRel插件的空指针报错,但是并不知道这个报错在哪里发生的(应该这下面还有一段),所以这个报错你给开发者
看也没啥用,给原作者看也不知道往哪里修


两千余字的教程,冒着不写作业的风险来写教程,如果觉得好可以给点人气~
来自群组: PluginsCDTribe

RainbowEna
本帖最后由 RainbowEna 于 2019-5-2 22:12 编辑

这是真正的干货!

另外提供常见关键词:

Update: 更新 - 往往和自动更新联系在一起
Config: 配置文件 - 往往和配置文件联系在一起,确保配置没有问题
getOnlinePlayer: 1.7到1.8交接时的Bukkit修改,版本不对实锤了
Effect/Sound: 指的是playEffect方法和playSound时出现的问题,版本不对的问题
enablePlugin/onEnable: 这种情况一般发生在服务器开服时加载插件出现问题
disablePlugin/onDisable: 这种情况一般发生在服务器关服时
http: 部分插件会以http协议获取更新,一般发生在自动更新的毛病
backup: 备份,部分插件拥有自动备份系统,可能会出现这个问题
Metrics: 一种统计系统,但若有Metrics的插件在报错时都可能含有
injector: 部分插件会尝试监控其他插件行为,比如Yum,这种报错不来源于这行报错指示的插件
Reflection: 反射,关于java开发的内容,这种情况一般出现在插件版本出错的情况下
StackOverFlow: 插件陷入死循环,大部分时候是作者的锅,也有可能是用户自己进行了死循环操作
async/asynchronous: 异步操作,大部分是插件作者的锅,尝试进行异步危险操作

Ariy
很好的教程!另外,强烈建议各位发报错的时候使用http://paste.ubuntu.org.cn/发布
尤其是长文!部分还花花绿绿的看着就辣眼睛!

弱鸡绿毛怪
tian_wc 发表于 2019-5-11 12:33
很好的教程!另外,强烈建议各位发报错的时候使用http://paste.ubuntu.org.cn/发布
尤其是长文!部分还花花 ...

感谢支持~~~

huangzhidong
这很可以啊,收藏一波

迂腐146
mcbbs有你真精彩

22743932
谢谢楼主 学会了