[BUG] Using ItemPredicate in another mod statically loads SpectrumBlocks too early, causing crashes
Fourmisain opened this issue ยท 3 comments
Describe the bug
This is a weird one, here's how we found it:
When Cozy Cabincore (Github) is installed together with Spectrum, any entity walking on Citrine blocks causes a crash because the block's SoundBlockGroup
is null
.
What's weirder is that Cozy Cabincore codewise doesn't even do anything special and only has 3 unrelated mixins (2 of which are accessors/invokers).
Looking further into it, it turns out that with Cozy Cabincore, SpectrumBlocks
is statically initialized before SpectrumBlockSoundGroups.init()
is called, hence SpectrumBlocks.CITRINE_BLOCK
is registered but the SpectrumBlockSoundGroups.CITRINE_BLOCK
is null
at that point.
Here's how this happens
Cozy Cabincore calls the ItemPredicate
constructor. Through Spectrum's ItemPredicateMixin
, SpectrumItems
is statically loaded, which in turn statically loads SpectrumBlocks
- all before SpectrumBlockSoundGroups.init()
, though that might depend on mod load order.
This can be seen by printing the stack trace at the beginning of SpectrumBlocks
, e.g.
static {
logInfo("SpectrumBlocks static init, SpectrumBlockSoundGroups.CITRINE_BLOCK = " + SpectrumBlockSoundGroups.CITRINE_BLOCK);
// print current stack trace
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
}
The log shows
Mixing ItemPredicateMixin from spectrum.mixins.json into net.minecraft.class_2073
[STDOUT]: java.base/java.lang.Thread.getStackTrace(Thread.java:1610)
[STDOUT]: de.dafuqs.spectrum.registries.SpectrumBlocks.<clinit>(SpectrumBlocks.java:122)
[STDOUT]: de.dafuqs.spectrum.registries.SpectrumItems.<clinit>(SpectrumItems.java:72)
[STDOUT]: net.minecraft.class_2073.localvar$zof000$addSpectrumShears(class_2073.java:524)
[STDOUT]: net.minecraft.class_2073.<init>(class_2073.java)
[STDOUT]: net.minecraft.class_2073$class_2074.method_8976(class_2073.java:274)
[STDOUT]: net.minecraft.class_223.method_944(class_223.java:39)
[STDOUT]: net.minecraft.class_186$class_187.<init>(class_186.java:48)
[STDOUT]: net.minecraft.class_186.method_826(class_186.java:65)
[STDOUT]: net.minecraft.class_5341$class_210.method_893(class_5341.java:20)
[STDOUT]: net.linkle.cozy.init.ModLootTable.<clinit>(ModLootTable.java:22)
[STDOUT]: net.linkle.cozy.CozyCabinCore.onInitialize(CozyCabinCore.java:33)
(...)
[Spectrum] SpectrumBlocks static init, SpectrumBlockSoundGroups.CITRINE_BLOCK = null
[Spectrum] Registering BlockSound Groups...
(...)
[Spectrum] Registering Blocks...
To Reproduce
Install Cozy Cabincore, load any world and try to place or walk on a Citrine block.
Mod version
Spectrum 1.4.1 (and Cozy Cabincore 1.1)
Crash Report
Placing a Citrine block down:
[Render thread/ERROR]: Unreported exception thrown!
java.lang.NullPointerException: Cannot invoke "net.minecraft.class_2498.method_10598()" because the return value of "net.minecraft.class_2680.method_26231()" is null
at Not Enough Crashes deobfuscated stack trace.(1.18.2+build.3) ~[?:?]
at net.minecraft.item.BlockItem.getPlaceSound(BlockItem:105) ~[?:?]
at net.minecraft.item.BlockItem.place(BlockItem:96) ~[?:?]
at net.minecraft.item.BlockItem.useOnBlock(BlockItem:50) ~[?:?]
class_2498
= BlockSoundGroup
Potential fix
This issue should be fixable by doing all the SpectrumBlockSoundGroups
initialization statically instead of relying on init()
being called.
While I could not reproduce it (mod load order sounds like the most logical issue here) I made the BlockSoundGroups initialize statically. Should solve that problem either way.
I haven't had issues with a player walking on citrine
with spectrum 1.4.1 and cozy cabincore 1.0