Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-7889

Tool component deserialization

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Minor Minor
    • None
    • None
    • This server is running CraftBukkit version dev-Spigot-5a6439b-8ee6fd1 (MC: 1.21.1) (Implementing API version 1.21.1-R0.1-SNAPSHOT)
    • Yes

      A user of one of my plugins came noticed an issue when the plugin tries to deserialize this item:

            item:
              ==: org.bukkit.inventory.ItemStack
              v: 3955
              type: OAK_LOG
              meta:
                ==: ItemMeta
                meta-type: UNSPECIFIC
                tool:
                  ==: Tool
                  default-mining-speed: 1.0
                  damage-per-block: 1
                  rules:
                  - ==: ToolRule
                    blocks: '#minecraft:incorrect_for_wodden_tool'
                    correct-for-drops: false
                  - ==: ToolRule
                    blocks: '#minecraft:mineable/hoe'
                    speed: 2.0
                    correct-for-drops: true 

       

      Error:

      Caused by: org.bukkit.configuration.InvalidConfigurationException: Could not call constructor 'public org.bukkit.craftbukkit.v1_21_R1.inventory.components.CraftToolComponent(java.util.Map)' of class org.bukkit.craftbukkit.v1_21_R1.inventory.components.CraftToolComponent for deserialization
              at com.nisovin.shopkeepers.util.bukkit.ConfigUtils.loadConfigSafely(ConfigUtils.java:259) ~[?:?]
              at com.nisovin.shopkeepers.util.data.persistence.bukkit.BukkitConfigDataStore.loadFromString(BukkitConfigDataStore.java:61) ~[?:?]
              ... 15 more
      Caused by: java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "obj" is null
              at org.bukkit.craftbukkit.v1_21_R1.inventory.components.CraftToolComponent.<init>(CraftToolComponent.java:50) ~[spigot-1.21.1-R0.1-SNAPSHOT.jar:dev-Spigot-5a6439b-8ee6fd1]
              at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62) ~[?:?]
              at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502) ~[?:?]
              at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486) ~[?:?]
              at org.bukkit.configuration.serialization.ConfigurationSerialization.deserializeViaCtor(ConfigurationSerialization.java:107) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.bukkit.configuration.serialization.ConfigurationSerialization.deserialize(ConfigurationSerialization.java:145) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.bukkit.configuration.serialization.ConfigurationSerialization.deserializeObject(ConfigurationSerialization.java:209) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.bukkit.configuration.file.YamlConstructor$ConstructCustomObject.construct(YamlConstructor.java:58) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:264) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:247) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping2ndStep(BaseConstructor.java:576) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.SafeConstructor.constructMapping2ndStep(SafeConstructor.java:210) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping(BaseConstructor.java:552) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.SafeConstructor$ConstructYamlMap.construct(SafeConstructor.java:597) ~[snakeyaml-2.2.jar:?]
              at org.bukkit.configuration.file.YamlConstructor$ConstructCustomObject.construct(YamlConstructor.java:49) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:264) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:247) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping2ndStep(BaseConstructor.java:576) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.SafeConstructor.constructMapping2ndStep(SafeConstructor.java:210) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping(BaseConstructor.java:552) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.SafeConstructor$ConstructYamlMap.construct(SafeConstructor.java:597) ~[snakeyaml-2.2.jar:?]
              at org.bukkit.configuration.file.YamlConstructor$ConstructCustomObject.construct(YamlConstructor.java:49) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:264) ~[snakeyaml-2.2.jar:?]
              at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:247) ~[snakeyaml-2.2.jar:?]
              at org.bukkit.configuration.file.YamlConstructor.construct(YamlConstructor.java:37) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.bukkit.configuration.file.YamlConfiguration.fromNodeTree(YamlConfiguration.java:162) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.bukkit.configuration.file.YamlConfiguration.fromNodeTree(YamlConfiguration.java:160) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.bukkit.configuration.file.YamlConfiguration.fromNodeTree(YamlConfiguration.java:160) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.bukkit.configuration.file.YamlConfiguration.fromNodeTree(YamlConfiguration.java:160) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]
              at org.bukkit.configuration.file.YamlConfiguration.loadFromString(YamlConfiguration.java:119) ~[spigot-api-1.21.1-R0.1-SNAPSHOT.jar:?]

      My guess of the issue is as follows:

      The first ToolRule has no 'speed' property. During deserialization, CraftToolComponent.CraftToolRule tries to load the 'speed' and 'correct-for-drops' properties as non-nullable, even though the properties appear to be nullable: During serialization they are omitted if null.

      For some reason, this unexpected missing value doesn't result in a deserialization error for the ToolRule, but ends up as a null value in the Iterable during the parent CraftToolComponent' deserialization, which then throws this NRE.

      After adding a speed value for the first ToolRule, the items loads fine.

            Unassigned Unassigned
            blablubbabc blablubbabc
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: