[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.

Generated at Tue Apr 08 02:45:40 UTC 2025 using Jira 10.3.3#10030003-sha1:d220e3fefc8dfc6d47f522d3b9a20c1455e12b7b.