Solved TileState is null

Discussion in 'Spigot Plugin Development' started by Maxigame99, Nov 21, 2021.

Thread Status:
Not open for further replies.
  1. it prints this error when i try to get the PersistentDataContainer

    Code (Text):
    [15:11:14 WARN]: [SkyBlock] Plugin SkyBlock v1.0 generated an exception while executing task 7506
    java.lang.RuntimeException: Failed to read BlockState at: world: SkyBlock location: (-1000, 58, -1000)
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftBlockEntityState.<init>(CraftBlockEntityState.java:48) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftContainer.<init>(CraftContainer.java:13) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftLootable.<init>(CraftLootable.java:16) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftChest.<init>(CraftChest.java:20) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock.getState0(CraftBlock.java:355) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock.getState(CraftBlock.java:326) ~[patched_1.16.5.jar:git-Paper-562]
            at net.minecraft.server.v1_16_R3.TileEntity.getOwner(TileEntity.java:265) ~[patched_1.16.5.jar:git-Paper-562]
            at net.minecraft.server.v1_16_R3.TileEntity.getOwner(TileEntity.java:253) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory.getHolder(CraftInventory.java:527) ~[patched_1.16.5.jar:git-Paper-562]
            at eu.skywonder.skyblock.listener.InventoryEvent.lambda$onClose$0(InventoryEvent.java:32) ~[?:?]
            at org.bukkit.craftbukkit.v1_16_R3.scheduler.CraftTask.run(CraftTask.java:100) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:54) ~[patched_1.16.5.jar:git-Paper-562]
            at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) ~[patched_1.16.5.jar:git-Paper-562]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
            at java.lang.Thread.run(Thread.java:834) [?:?]
    Caused by: java.lang.IllegalStateException: Tile is null, asynchronous access? CraftBlock{pos=BlockPosition{x=-1000, y=58, z=-1000},type=CHEST,data=Block{minecraft:chest}[facing=north,type=single,waterlogged=false],[email protected]}
            at com.google.common.base.Preconditions.checkState(Preconditions.java:518) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftBlockEntityState.<init>(CraftBlockEntityState.java:29) ~[patched_1.16.5.jar:git-Paper-562]
            ... 15 more
    this is my code:
    Code (Java):
        private static void generate(Location location, ItemStack... items) {
            if (!Bukkit.isPrimaryThread()) {
                Bukkit.getScheduler().runTask(SkyBlock.getInstance(), () -> generate(location, items));
                return;
            }
            Block block = location.getBlock();
            if (block.isBuildable())
                block.breakNaturally();
            // Create a new chest
            block.setType(Material.CHEST);
            Chest chest = (Chest) block.getState(true);
            chest.setCustomName(CHEST_NAME);
            // Setup the persistent data container
            PersistentDataContainer container = chest.getPersistentDataContainer();
            container.set(new NamespacedKey(SkyBlock.getInstance(), "rewardChest"), PersistentDataType.BYTE, (byte) 1);
            chest.setMetadata("breakable", new FixedMetadataValue(SkyBlock.getInstance(), false));
            // Add the items
            Inventory inv = chest.getBlockInventory();
            final int length = items.length;
            int[] ints = new Random().ints(0, 27).distinct().limit(length).toArray();
            for (int n = 0; n < length; n++)
                inv.setItem(ints[n], items[n]);
            block.getState().update();
        }
    it seems strange to me that the method could be called in another thread, since I added a check. Any advise?
     
  2. You may be scheduling the task on the main thread
     
  3. Code (Java):
            if (!Bukkit.isPrimaryThread()) {
                Bukkit.getScheduler().runTask(SkyBlock.getInstance(), () -> generate(location, items));
                return;
            }
    is this not enough?
     
  4. Code (Java):
        private static void generate(Location location, ItemStack... items) {
            if (!Bukkit.isPrimaryThread()) {
                Bukkit.getScheduler().runTask(SkyBlock.getInstance(), () -> generate(location, items));
                return;
            }
            Bukkit.getScheduler().scheduleSyncDelayedTask(SkyBlock.getInstance(), ()->{
                Block block = location.getBlock();
                if (block.isBuildable())
                    block.breakNaturally();
                // Create a new chest
                block.setType(Material.CHEST);
                Chest chest = (Chest) block.getState();
                chest.setCustomName(CHEST_NAME);
                // Setup the persistent data container
                PersistentDataContainer container = chest.getPersistentDataContainer();
                container.set(new NamespacedKey(SkyBlock.getInstance(), "rewardChest"), PersistentDataType.BYTE, (byte) 1);
                chest.setMetadata("breakable", new FixedMetadataValue(SkyBlock.getInstance(), false));
                // Add the items
                Inventory inv = chest.getBlockInventory();
                final int length = items.length;
                int[] ints = new Random().ints(0, 27).distinct().limit(length).toArray();
                for (int n = 0; n < length; n++)
                    inv.setItem(ints[n], items[n]);
                block.getState().update();
            });
        }
    I do it so, but the error remains
     
  5. Just try to remove the check and use it only on the main Thread
     
    • Agree Agree x 1
  6. I believe even if you check if the thread is not the main thread, you can still schedule on the main thread.
     
  7. Can you send me an example of the code, because it keeps giving me the same error even when running it in the main thread.
     
  8. it's already the server thread look the image below.
     

    Attached Files:

  9. Is this method called inside onEnable() in main class?
    Try that:
    Code (Java):

    BlockState state = block.getState();
    state.setType(Material.CHEST)
    state.update(true)
    Chest chest = (Chest)block.getState();
    instead of that:


    Code (Text):
    block.setType(Material.CHEST);
    Chest chest = (Chest) block.getState(true);
     
     
  10. No, the method ins't called inside the onEnable().
    This is now my version:
    Code (Text):
        private static void generate(Location location, ItemStack... items) {
            if (!Bukkit.isPrimaryThread()) {
                Bukkit.getScheduler().runTask(SkyBlock.getInstance(), () -> generate(location, items));
                return;
            }
            Block block = location.getBlock();
            if (block.isBuildable())
                block.breakNaturally();
            // Create a new chest
            BlockState state = block.getState();
            state.setType(Material.CHEST);
            state.update(true);
            Chest chest = (Chest) block.getState();
            chest.setCustomName(CHEST_NAME);
            // Setup the persistent data container
            PersistentDataContainer container = chest.getPersistentDataContainer();
            container.set(new NamespacedKey(SkyBlock.getInstance(), "rewardChest"), PersistentDataType.BYTE, (byte) 1);
            chest.setMetadata("breakable", new FixedMetadataValue(SkyBlock.getInstance(), false));
            // Add the items
            Inventory inv = chest.getBlockInventory();
            final int length = items.length;
            int[] ints = new Random().ints(0, 27).distinct().limit(length).toArray();
            for (int n = 0; n < length; n++)
                inv.setItem(ints[n], items[n]);
            chest.update(true);
        }
    end this is the error (the same):
    Code (Text):
    [09:15:12 WARN]: [SkyBlock] Plugin SkyBlock v1.0 generated an exception while executing task 24010
    java.lang.RuntimeException: Failed to read BlockState at: world: SkyBlock location: (-1000, 58, -1000)
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftBlockEntityState.<init>(CraftBlockEntityState.java:48) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftContainer.<init>(CraftContainer.java:13) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftLootable.<init>(CraftLootable.java:16) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftChest.<init>(CraftChest.java:20) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock.getState0(CraftBlock.java:355) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock.getState(CraftBlock.java:326) ~[patched_1.16.5.jar:git-Paper-562]
            at net.minecraft.server.v1_16_R3.TileEntity.getOwner(TileEntity.java:265) ~[patched_1.16.5.jar:git-Paper-562]
            at net.minecraft.server.v1_16_R3.TileEntity.getOwner(TileEntity.java:253) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory.getHolder(CraftInventory.java:527) ~[patched_1.16.5.jar:git-Paper-562]
            at eu.skywonder.skyblock.listener.InventoryEvent.lambda$onClose$0(InventoryEvent.java:32) ~[?:?]
            at org.bukkit.craftbukkit.v1_16_R3.scheduler.CraftTask.run(CraftTask.java:100) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:54) ~[patched_1.16.5.jar:git-Paper-562]
            at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) ~[patched_1.16.5.jar:git-Paper-562]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
            at java.lang.Thread.run(Thread.java:834) [?:?]
    Caused by: java.lang.IllegalStateException: Tile is null, asynchronous access? CraftBlock{pos=BlockPosition{x=-1000, y=58, z=-1000},type=CHEST,data=Block{minecraft:chest}[facing=north,type=single,waterlogged=false],[email protected]}
            at com.google.common.base.Preconditions.checkState(Preconditions.java:518) ~[patched_1.16.5.jar:git-Paper-562]
            at org.bukkit.craftbukkit.v1_16_R3.block.CraftBlockEntityState.<init>(CraftBlockEntityState.java:29) ~[patched_1.16.5.jar:git-Paper-562]
            ... 15 more
     
     
  11. dont check the thread first,simply run the entire method code inside the runTask,dont loop around without a reason,it has to run on the main thread no matter what
     
  12. Code (Text):
        private static void generate(Location location, ItemStack... items) {
            /*if (!Bukkit.isPrimaryThread()) {
                Bukkit.getScheduler().runTask(SkyBlock.getInstance(), () -> generate(location, items));
                return;
            }*/
            Bukkit.getScheduler().runTask(SkyBlock.getInstance(), ()->{
                Bukkit.broadcastMessage("Thread Name: "+Thread.currentThread().getName());
                Block block = location.getBlock();
                if (block.isBuildable())
                    block.breakNaturally();
                // Create a new chest
                BlockState state = block.getState();
                state.setType(Material.CHEST);
                state.update(true);
                Chest chest = (Chest) block.getState();
                chest.setCustomName(CHEST_NAME);
                // Setup the persistent data container
                PersistentDataContainer container = chest.getPersistentDataContainer();
                container.set(new NamespacedKey(SkyBlock.getInstance(), "rewardChest"), PersistentDataType.BYTE, (byte) 1);
                chest.setMetadata("breakable", new FixedMetadataValue(SkyBlock.getInstance(), false));
                // Add the items
                Inventory inv = chest.getBlockInventory();
                final int length = items.length;
                int[] ints = new Random().ints(0, 27).distinct().limit(length).toArray();
                for (int n = 0; n < length; n++)
                    inv.setItem(ints[n], items[n]);
                chest.update(true);
            });
    }
    the thread output name: "Server thread"
    and it launch the same error -.-
     
  13. how are you triggering generate() method?
     
  14. upload_2021-11-25_21-17-3.png

    and the spawn method is called in an upgrade listener.
     
  15. Thats not the greatest solution, but try that:

    Bukkit.getScheduler().scheduleSyncDelayedTask(MainClass.getPlugin(MainClass.class), (Runnable) () -> generate(),1);
     
Thread Status:
Not open for further replies.