RictAcius RictAcius - 1 month ago 14
Java Question

Date Parsing Operation Crashes Server

I am creating a Spigot plugin, but this chunk of code keeps crashing my server.

public List<String> getReports(OfflinePlayer p) {
FileConfiguration config = getData(p);
List<String> reports = new ArrayList<String>();
for (String item : config.getConfigurationSection("reports").getKeys(false)) {
try {
Date created = dateFormat.parse(config.getString("reports." + item + ".date"));
if (!reports.isEmpty()) {
boolean added = false;
for (int i = 0; i < reports.size(); i++) {
try {
String e = reports.get(i);
String edate = config.getString("reports." + e + ".date");
Date eday = dateFormat.parse(edate);
if (created.after(eday) || created.equals(eday)) {
reports.add(i, item);
added = true;
}
} catch (Throwable e) {
e.printStackTrace();
}
}
if (!added) {
reports.add(item);
}
} else {
reports.add(item);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return reports;
}


I know that an Invalid date strings will throw a ParseException, but no error is thrown. I even tried catching a Throwable instead, but that did nothing. The strings are valid and are imported correctly by my plugin (I checked), and this method works with 1-2 items but any more will break it for some reason.

Here is my data (YAML):

reports:
'1':
type: Misc
source: 6db6fde9-802f-4bef-a40a-fe516a7a8309
reason: Idk
date: 28/10/2016 19:09:16
'2':
type: Grief
source: 6db6fde9-802f-4bef-a40a-fe516a7a8309
reason: He destroyed my building! And he did really nasty stuff too meh, ban him now!
date: 28/10/2016 19:14:56
'3':
type: Hacking
source: 6db6fde9-802f-4bef-a40a-fe516a7a8309
reason: He was flying like mad all over the place. This guy needs to be banned!
date: 28/10/2016 19:29:33


What the method is attempting to do, is import data from a player's history and sort it in reverse chronological order. I've never seen something like this happen before, it isn't even documented for something like this to happen. I know I must be doing one really stupid thing, but I need help finding out what that is.

Edit:
Here is my dateformat feild

public final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.US);


Edit: Even though I already said no specific error was thrown, here's a stack trace that doesnt help

[10:08:18] [Spigot Watchdog Thread/ERROR]: The server has stopped responding!
[10:08:18] [Spigot Watchdog Thread/ERROR]: Please report this to http://www.spigotmc.org/
[10:08:18] [Spigot Watchdog Thread/ERROR]: Be sure to include ALL relevant console errors and Minecraft crash reports
[10:08:18] [Spigot Watchdog Thread/ERROR]: Spigot version: git-Spigot-5f38d38-18fbb24 (MC: 1.8.8)
[10:08:18] [Spigot Watchdog Thread/ERROR]: ------------------------------
[10:08:18] [Spigot Watchdog Thread/ERROR]: Server thread dump (Look for plugins here before reporting to Spigot!):
[10:08:18] [Spigot Watchdog Thread/ERROR]: ------------------------------
[10:08:18] [Spigot Watchdog Thread/ERROR]: Current Thread: Server thread
[10:08:18] [Spigot Watchdog Thread/ERROR]: PID: 16 | Suspended: false | Native: false | State: RUNNABLE
[10:08:18] [Spigot Watchdog Thread/ERROR]: Stack:
[10:08:18] [Spigot Watchdog Thread/ERROR]: java.text.DecimalFormat.parse(Unknown Source)
[10:08:18] [Spigot Watchdog Thread/ERROR]: java.text.SimpleDateFormat.subParse(Unknown Source)
[10:08:18] [Spigot Watchdog Thread/ERROR]: java.text.SimpleDateFormat.parse(Unknown Source)
[10:08:18] [Spigot Watchdog Thread/ERROR]: java.text.DateFormat.parse(Unknown Source)
[10:08:18] [Spigot Watchdog Thread/ERROR]: com.rictacius.punishSystem.system.History.getReports(History.java:155)
[10:08:18] [Spigot Watchdog Thread/ERROR]: com.rictacius.punishSystem.gui.PunishMenu.getReportsBar(PunishMenu.java:57)
[10:08:18] [Spigot Watchdog Thread/ERROR]: com.rictacius.punishSystem.gui.PunishMenu.getMainMenu(PunishMenu.java:41)
[10:08:18] [Spigot Watchdog Thread/ERROR]: com.rictacius.punishSystem.command.PunishCommand.onCommand(PunishCommand.java:62)
[10:08:18] [Spigot Watchdog Thread/ERROR]: org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
[10:08:18] [Spigot Watchdog Thread/ERROR]: org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141)
[10:08:18] [Spigot Watchdog Thread/ERROR]: org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:641)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1162)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:997)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:45)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:1)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13)
[10:08:18] [Spigot Watchdog Thread/ERROR]: java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
[10:08:18] [Spigot Watchdog Thread/ERROR]: java.util.concurrent.FutureTask.run(Unknown Source)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:715)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654)
[10:08:18] [Spigot Watchdog Thread/ERROR]: net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557)
[10:08:18] [Spigot Watchdog Thread/ERROR]: java.lang.Thread.run(Unknown Source)


The last item in the stack that has to do with me is this line

Date eday = dateFormat.parse(edate);

Answer

The reason that my server keeps crashing is because it runs out of memory.

(From: @Jon Skeet) The fact that you're looping over a collection and conditionally adding to it looks suspect to me. It's possible that it's just looping forever, because it adds an item, then finds that item and adds another, then adds another etc. The stack trace you've got may just be one that was taken within the infinite loop, or possibly on running out of memory. You should be adding more diagnostics so you can see how the code is executing.

By looping through a collection that I am adding values to is not correct, because what would end up happening is that objects will continue to be added at the same position forever.

Instead what I should have done is to sort the array after it's been populated. A simple shuttle sort would have fixed this.