[SPIGOT-4825] Calling getState() from sign block in asynchronous tasks produces NPEs Created: 30/Apr/19  Updated: 01/May/19  Resolved: 01/May/19

Status: Resolved
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Eirik Hetland Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

java1.8

Windows 10


Attachments: File test-1.0-SNAPSHOT.jar    
Version: This server is running CraftBukkit version git-Spigot-1eece4f-dadc539 (MC: 1.14) (Implementing API version 1.14-R0.1-SNAPSHOT)
Plugin: test
Guidelines Read: Yes

 Description   

When trying to get the BlockState from a sign block by calling getState() and casting it to Sign in an async task, it produces a NullPointerException. This never happened in 1.13 and previous versions

This is affecting Spigot version 1.14

How to reproduce

  1. Install the plugin supplied here on your server.
  2. Start your server
  3. Place a sign in the world and add text
  4. Get a wooden shovel, right-click the sign and watch the console output

My plugin's source code:

package io.github.eirikh1996;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class Test extends JavaPlugin implements Listener {
    @Override
    public void onEnable() {
        getServer().getPluginManager().registerEvents(this,this);
    }

    @EventHandler
    public void onBlockClick(PlayerInteractEvent event){
        if (!event.getAction().equals(Action.RIGHT_CLICK_BLOCK)){
            return;
        }
        if (!event.getItem().getType().equals(Material.WOODEN_SHOVEL)){
            return;
        }
        event.setCancelled(true);
        if (event.getClickedBlock().getState() instanceof Sign){
            final Block block = event.getClickedBlock();
            new BukkitRunnable() {
                @Override
                public void run() {
                    Sign sign = (Sign) block.getState();
                    Player p = event.getPlayer();
                    p.sendMessage(event.getClickedBlock().getType().name() + ": ");
                    for (String s : sign.getLines()){
                        if (s == null) continue;
                        p.sendMessage(s);
                    }
                }
            }.runTaskAsynchronously(this);

        }
    }
}

Console output:

[19:25:04] [Craft Scheduler Thread - 0/WARN]: [Test] Plugin Test v1.0 generated an exception while executing task 40
java.lang.NullPointerException: null
        at org.bukkit.craftbukkit.v1_14_R1.block.CraftSign.load(CraftSign.java:30) ~[spigot-1.14.jar:git-Spigot-1eece4f-dadc539]
        at org.bukkit.craftbukkit.v1_14_R1.block.CraftSign.load(CraftSign.java:1) ~[spigot-1.14.jar:git-Spigot-1eece4f-dadc539]
        at org.bukkit.craftbukkit.v1_14_R1.block.CraftBlockEntityState.<init>(CraftBlockEntityState.java:30) ~[spigot-1.14.jar:git-Spigot-1eece4f-dadc539]
        at org.bukkit.craftbukkit.v1_14_R1.block.CraftSign.<init>(CraftSign.java:19) ~[spigot-1.14.jar:git-Spigot-1eece4f-dadc539]
        at org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock.getState(CraftBlock.java:330) ~[spigot-1.14.jar:git-Spigot-1eece4f-dadc539]
        at io.github.eirikh1996.Test$1.run(Test.java:37) ~[?:?]
        at org.bukkit.craftbukkit.v1_14_R1.scheduler.CraftTask.run(CraftTask.java:81) ~[spigot-1.14.jar:git-Spigot-1eece4f-dadc539]
        at org.bukkit.craftbukkit.v1_14_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:54) [spigot-1.14.jar:git-Spigot-1eece4f-dadc539]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:1.8.0_201]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:1.8.0_201]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_201]

Finally:

I tested the code in the new BukkitRunnable clause while running it sync as well, which caused no issues to occur. It only occurs if the same code is run async.



 Comments   
Comment by Black Hole [ 30/Apr/19 ]

It wasn't supported there either. If something is working most of the time it doesn't implicate that it's supported.
Plugins using methods that are not supposed to be called outside of the main thread can cause many unexpected behavior. Spigot have a lot of catchers for this.

Comment by md_5 [ 30/Apr/19 ]

Touching the world Async in Bukkit has never been supported.

Just because it didn't crash instantly every time in 1.13 doesn't mean it wouldn't crash or wasn't otherwise broken.

 

Anyway reopening this as the last commit needs to be reverted and the error done differently.

Comment by Eirik Hetland [ 30/Apr/19 ]

Creating BlockStates async not supported is new to 1.14 right? cause it was no problem in 1.13

Comment by md_5 [ 30/Apr/19 ]

Clear error now given

Comment by Black Hole [ 30/Apr/19 ]

Creating BlockStates asynchronously is not supported. You have to create the BlockState in the main thread before using it in another thread.

For help doing so please use the Spigot forums.

Generated at Sat Dec 13 20:46:18 UTC 2025 using Jira 10.3.13#10030013-sha1:56dd970ae30ebfeda3a697d25be1f6388b68a422.