I'm writing my code using Jetbrains IntellliJ. When I run this code through the IDE, everything behaves as intended. Yet when I build the mod (using gradle build) and run the compiled JAR through a Forge server, I get NoSuchField exceptions thrown. I'm honestly baffled by this.
Can anyone help me understand why the two versions are behaving differently?
The purpose of this getting of private variables is a workaround for using potion's NBT data in crafting recipes, which is not supported by the JSON format. On item initialisation, the ItemPotionArmor's material, slot and potion name are added to a dictionary, using these concatenated strings as a key, and the instance of the ItemPotionArmor as a value. This dictionary is later used by the ShapedArmorUpgradeRecipe crafting recipe class. Once it has confirmed that the right vanilla items are present in crafting grid, it takes the previously mentioned values from the vanilla armor / potions in the grid, concatenates them together, and retrieves the relevant ItemPotionArmor instance to pass back as a result.
The ModItems.getMaterialName is called during item initialisation, in the preInit stage of mod loading. You can see the exceptions being thrown and printed in the server logs at this time. It is also called again when the final item in the recipe is placed in the crafting grid. To test, I've been using standard fire resistance potions and any armor piece.
There's no stacktrace as there's no crash (it's a handled exception).
In summary, Minecraft code is obfuscated, so fields are named differently in the dev and compiled version. The fields I'm looking for when coding in my IDE are named "name" and "ArmorType". Once compiled, these are named something like "field_177856_a", so my reflection methods couldn't find them.