How do I access SpongeAPI from off main thread?


#1

Please help :dizzy_face::blush:


----------------------------ERROR-----------------------------

---------------------------RawData----------------------------
[01:23:37] [Thread-38/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:-1]: java.lang.IllegalStateException: CauseStackManager called from off main thread (current=‘HandlerThread{class=class net.HandlerThread, name=Thread-38, priority=5, group=net.minecraftforge.fml.common.thread.SidedThreadGroup[name=SERVER,maxpri=10]}’, expected=‘Thread{class=class java.lang.Thread, name=Server thread, priority=5, group=net.minecraftforge.fml.common.thread.SidedThreadGroup[name=SERVER,maxpri=10]}’)!
[01:23:37] [Thread-38/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:-1]: at org.spongepowered.common.event.SpongeCauseStackManager.enforceMainThread(SpongeCauseStackManager.java:71)
[01:23:37] [Thread-38/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:-1]: at org.spongepowered.common.event.SpongeCauseStackManager.pushCause(SpongeCauseStackManager.java:107)
[01:23:37] [Thread-38/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:-1]: at org.spongepowered.common.command.SpongeCommandManager.process(SpongeCommandManager.java:298)
[01:23:37] [Thread-38/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:-1]: at net.HandlerThread.run(HandlerThread.java:46)


#2

No, just no. First off, you need to understand that Minecraft is single-threaded, and there are a number of actions that you simply cannot do asynchronously. Commands is a huge part of this as they often rely on player entities, a Cause, and return a CommandResult used by command blocks. Processing a command needs to be done in on the server, so if you are currently async you can use the Scheduler to execute code in sync.

Without going into too much detail, I’m going to mention three issues with your code. First, your try-catch blocks continue after catching an exception which will cause a NPE rather quickly. You are also trying to get a player asynchronously and are not ensuring that the player is present - if the player isn’t there, that’ll throw a NSEE. Finally, I have no idea what you’re trying to do with string parsing of commands. I strongly recommend that you simply create a command instead of hardcoding things, which you can find info for here. If you do need to execute a command from a string, then you can use CommandManager#process synchronously.

Please be careful with your code and understand the systems you are trying to use; you have both explanatory docs and javadocs available. Just because it compiles doesn’t mean it’s right.


#3

To add on to @Simon_Flash’s answer, when you have finished executing code asynchronously and need to start executing code synchronously, create a Task with a lambda for the desired code and submit it.


#4

Thanks for your answering.:grin:
I did my best…
But the problem still remaining unsolved :sob:


#5

Thanks for your answering.:grinning: