EngineHub / CommandHelper

Rapid scripting and command aliases for Minecraft owners
https://methodscript.com
Other
119 stars 71 forks source link

Rare PersistenceNetwork NPE #1147

Open LadyCailinBot opened 7 years ago

LadyCailinBot commented 7 years ago

CMDHELPER-3153 - Reported by PseudoKnight

Not sure what's going on here, but I thought I'd add this to keep track of it. This code has run countless times with no issue.

[22:33:56] [Server thread/ERROR]: Uh oh! You've found an error in Core.
This is an error caused while running your code, so you may be able to find a workaround, but is ultimately an error in Core itself.
The line of code that caused the error was this:
get_value('uuids', @uuid)
on or around /plugins/CommandHelper/LocalPackages/auto_include.ms:408.
Please report this error to the developers, and be sure to include the version numbers:
Server version: 1.12-R0.1-SNAPSHOT;
CommandHelper version: 3.3.2-SNAPSHOT.3201-;
Loaded extensions and versions:
CHPerms (version 2.0.0);
CHSerialize (version 0.0.1);
CHSpigot (version 1.5.1);
CHPaper (version 0.0.1);
CHFiles (version 2.1.2);
CHStargate (version 2.0.0);
CHNaughty (version 3.4.3);
CHDynmap (version 1.1.3);
CHVirtualChests (version 1.0.5);
SKCompat (version 2.1.0);
Core (version 3.3.2);
Here's the stacktrace:
java.lang.NullPointerException
    at com.laytonsmith.persistence.PersistenceNetwork.get(PersistenceNetwork.java:104)
    at com.laytonsmith.core.functions.Persistence$get_value.exec(Persistence.java:181)
    at com.laytonsmith.core.Script.eval(Script.java:375)
    at com.laytonsmith.core.Script.eval(Script.java:344)
    at com.laytonsmith.core.Procedure.execute(Procedure.java:219)
    at com.laytonsmith.core.Procedure.cexecute(Procedure.java:169)
    at com.laytonsmith.core.Script.eval(Script.java:304)
    at com.laytonsmith.core.Script.eval(Script.java:344)
    at com.laytonsmith.core.Script.eval(Script.java:344)
    at com.laytonsmith.core.functions.DataHandling$foreach.execs(DataHandling.java:781)
    at com.laytonsmith.core.Script.eval(Script.java:334)
    at com.laytonsmith.core.Script.seval(Script.java:253)
    at com.laytonsmith.core.functions.BasicLogic$_if.execs(BasicLogic.java:85)
    at com.laytonsmith.core.Script.eval(Script.java:334)
    at com.laytonsmith.core.Script.eval(Script.java:344)
    at com.laytonsmith.core.Script.seval(Script.java:253)
    at com.laytonsmith.core.functions.BasicLogic$_switch.execs(BasicLogic.java:411)
    at com.laytonsmith.core.Script.eval(Script.java:334)
    at com.laytonsmith.core.MethodScriptCompiler.execute(MethodScriptCompiler.java:2001)
    at com.laytonsmith.core.MethodScriptCompiler.execute(MethodScriptCompiler.java:1958)
    at com.laytonsmith.core.Script.run(Script.java:207)
    at com.laytonsmith.core.AliasCore.alias(AliasCore.java:153)
    at com.laytonsmith.commandhelper.CommandHelperListener.runAlias(CommandHelperListener.java:80)
    at com.laytonsmith.commandhelper.CommandHelperListener.onPlayerCommandPreprocess(CommandHelperListener.java:112)
    at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor30.execute(Unknown Source)
    at org.bukkit.plugin.EventExecutor$1.execute(EventExecutor.java:44)
    at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:78)
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:514)
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:499)
    at net.minecraft.server.v1_12_R1.PlayerConnection.handleCommand(PlayerConnection.java:1416)
    at net.minecraft.server.v1_12_R1.PlayerConnection.a(PlayerConnection.java:1229)
    at net.minecraft.server.v1_12_R1.PacketPlayInChat.a(PacketPlayInChat.java:45)
    at net.minecraft.server.v1_12_R1.PacketPlayInChat.a(PacketPlayInChat.java:5)
    at net.minecraft.server.v1_12_R1.PlayerConnectionUtils.lambda$ensureMainThread$0(PlayerConnectionUtils.java:14)
    at net.minecraft.server.v1_12_R1.PlayerConnectionUtils$$Lambda$32/1449009888.run(Unknown Source)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at net.minecraft.server.v1_12_R1.SystemUtils.a(SourceFile:46)
    at net.minecraft.server.v1_12_R1.MinecraftServer.D(MinecraftServer.java:842)
    at net.minecraft.server.v1_12_R1.DedicatedServer.D(DedicatedServer.java:423)
    at net.minecraft.server.v1_12_R1.MinecraftServer.C(MinecraftServer.java:766)
    at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:664)
    at java.lang.Thread.run(Unknown Source)
LadyCailin commented 4 years ago

The code here has moved around some, but looking through the history, I now see that this corresponds to here (PersistenceNetworkImpl.java#L99), on the ds.get(key) line, so this must be ThreadsafeDataSource.GetDataSource returning null.

Looking at that code, I see that SOURCES is a WeakHashMap, and the thing about WeakHashMaps is that they use the WeakReference class, so the values in the Map could just.. go away from time to time, if nothing is concretely using them.

That said, there is still a check there:

ThreadsafeDataSource source = SOURCES.get(pair);
if(source != null) {
    return source;
} else {
    ThreadsafeDataSource ds = new ThreadsafeDataSource(DataSourceFactory.GetDataSource(uri, options));
    SOURCES.put(pair, ds);
    return ds;
}

So if the source is null, we build a new one. The WeakHashMap only uses WeakReferences on the keys though, so.. I feel sure that this is related, but I can't see how. If we're about to return null, we don't, and in the else case, we return ds (guaranteed not null) so.. there must be something else going on here, but I don't understand it.