[SPIGOT-7185] Can't catch item deserialization errors Created: 19/Nov/22 Updated: 25/Dec/24 Resolved: 19/Nov/22 |
|
Status: | Closed |
Project: | Spigot |
Component/s: | None |
Affects Version/s: | None |
Fix Version/s: | None |
Type: | Bug | Priority: | Minor |
Reporter: | Donato Gentile | Assignee: | Unassigned |
Resolution: | Done | Votes: | 0 |
Labels: | bug | ||
Environment: |
Windows 10 Professional 22H2 Intel Core I7 4770K 16Gb DDR3 1600Mhz |
Version: | 3607-Spigot-6198b5a-e7aab54 (MC: 1.19.2) |
Plugin: | CustomFishing 1.2.8 |
Guidelines Read: | Yes |
Description |
If a skull is corrupted and saved into the database, when trying to reload the skull and deserializing it, it will throw an error. I tried to catch the error to handle it, but it seems that it does not propagate to the call of the deserialization and so makes the error not catchable. Error: [[05:59:19 ERROR]: org.bukkit.configuration.serialization.ConfigurationSerializa - Pastebin.com Here is the code to retrieve the data and decode and then deserialize. It works with any known good item (including skulls). public static ItemStack[] itemStackArrayFromBase64(String data) throws IOException { try { ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data)); BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream); ItemStack[] items = new ItemStack[dataInput.readInt()]; for (int Index = 0; Index < items.length; Index++) { @SuppressWarnings("unchecked") Map<String, Object> stack = (Map<String, Object>) dataInput.readObject(); try { items[Index] = stack != null ? ItemStack.deserialize(stack) : new ItemStack(Material.AIR); } catch (Exception e) { items[Index] = new ItemStack(Material.PLAYER_HEAD); Bukkit.getLogger().warning("An item has been replaced by a player head because it couldn't be deserialized."); Bukkit.getLogger().warning("Item that couldn't be deserialized had the following data: " + (stack != null ? stack.toString() : "null")); } } dataInput.close(); return items; } catch (ClassNotFoundException e) { throw new IOException("Unable to decode class type.", e); } } |
Comments |
Comment by Donato Gentile [ 19/Nov/22 ] |
Oh... So, I just have to place the dataInput.readObject inside my try/catch. Gonna try it. Thanks for pointing it out, I misread the stack trace :/ |
Comment by Black Hole [ 19/Nov/22 ] |
The exception occurs within BukkitObjectInputStream.resolveObject(), where you're only catching ClassNotFoundException. |
Comment by Donato Gentile [ 19/Nov/22 ] |
Sorry, I forgot to place in the error... Here it is: [[05:59:19 ERROR]: org.bukkit.configuration.serialization.ConfigurationSerializa - Pastebin.com |
Comment by Phoenix616 [ 19/Nov/22 ] |
Kinda not related to your actual issue but I strongly recommend not using object deserialization from datastreams like that. This is discouraged by the Java devs and is alreay planed to be deprecated and removed in a future Java version. I would suggest either using your own format, storing the ItemStack in a yaml string and storing that in the database (if you want to keep compatible with the plugin API), or directly store the NBT. (Would require nms though) |
Comment by Black Hole [ 19/Nov/22 ] |
What Exception are you receiving? readObject() could throw several other exceptions beside ClassNotFoundException. You're using an ItemStack instance. If that ItemStack is later added to an inventory this instance is converted to a Minecraft item stack. It's possible that you receive exceptions at that point. |