Issue with custom data

So I just ran into a weird issue while retrieving custom data composed of an object that contains a String and a Map<String, List<BlockSnapshot>>. The data is offered successfully to the block (has to be a chest in the case of my test plugin), and I can successfully retrieve it, but after the server is restarted, it throws an exception while retrieving the data (I assume it is an issue deserializing). My test plugin is here, and this is the exception it throws:

[15:56:17] [Server thread/ERROR] [Sponge]: Could not pass InteractBlockEvent$Secondary$Impl to org.spongepowered.mod.plugin.SpongeModPluginContainer@2f7c0a05
java.lang.ClassCastException: com.google.common.collect.RegularImmutableMap cannot be cast to org.spongepowered.api.block.BlockSnapshot
	at me.reherhold.test.TestPlugin.blockInteract(TestPlugin.java:43) ~[TestPlugin.class:?]
	at org.spongepowered.common.event.listener.SecondaryListener_TestPlugin_blockInteract4.handle(Unknown Source) ~[?:?]
	at org.spongepowered.common.event.RegisteredListener.handle(RegisteredListener.java:86) ~[RegisteredListener.class:1.8.9-1808-4.1.0-BETA-1234]
	at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:239) [SpongeModEventManager.class:1.8.9-1808-4.1.0-BETA-1234]
	at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:199) [SpongeModEventManager.class:1.8.9-1808-4.1.0-BETA-1234]
	at net.minecraftforge.event.ForgeEventFactory.onPlayerInteract(ForgeEventFactory.java:60) [ForgeEventFactory.class:?]
	at net.minecraft.server.management.ItemInWorldManager.func_180236_a(ItemInWorldManager.java:403) [lg.class:?]
	at net.minecraft.network.NetHandlerPlayServer.redirect$onActivateBlockOrUseItem$0(NetHandlerPlayServer.java:110) [lm.class:?]
	at net.minecraft.network.NetHandlerPlayServer.func_147346_a(NetHandlerPlayServer.java:588) [lm.class:?]
	at net.minecraft.network.play.client.C08PacketPlayerBlockPlacement.func_148833_a(SourceFile:59) [ja.class:?]
	at net.minecraft.network.play.client.C08PacketPlayerBlockPlacement.func_148833_a(SourceFile:10) [ja.class:?]
	at org.spongepowered.common.network.PacketUtil.onProcessPacket(PacketUtil.java:106) [PacketUtil.class:1.8.9-1808-4.1.0-BETA-1234]
	at net.minecraft.network.PacketThreadUtil$1.redirect$onProcessPacket$0(SourceFile:51) [fh$1.class:?]
	at net.minecraft.network.PacketThreadUtil$1.run(SourceFile:13) [fh$1.class:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_45-internal]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_45-internal]
	at net.minecraft.util.Util.func_181617_a(SourceFile:44) [g.class:?]
	at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:660) [MinecraftServer.class:?]
	at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:344) [ko.class:?]
	at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:605) [MinecraftServer.class:?]
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:481) [MinecraftServer.class:?]
	at java.lang.Thread.run(Thread.java:745) [?:1.8.0_45-internal]

Interestingly enough, my actual plugin with more or less the same code throws an exception trying to cast from com.google.common.collect.SingletonImmutableBiMap to java.util.List, but I’ll settle for figuring this out first.

There’s your problem. You’re assuming that the container has already deserialized the list of blocksnapshots. Then when you try an access an object from that map, turns out it’s not a list of snapshots, but a list of maps.

The data container only ever contains basic types like primitives, lists, sub-views, etc. You have to specifically tell it to deserialize a data type for it to work as you expect.

Because you’re deserializing a map, that means that you can get the DataView backing that Map, and then deserialize each of the entries in that map, calling DataView#getSerializableList(DataQuery, Class<?>) on each of the keys in DataView#getKeys(false).

Thanks! Never would have thought of that.