3

I have an API library which uses Retrofit (and the GsonConverterFactory) to send requests and parse the responses into Java objects. This is working fine - but when I try and use the library from within a bukkit plugin, I get this error when trying to execute a request (both sync and async - using the Bukkit async methods and the Retrofit enqueue() method):

   Could not pass event AsyncPlayerChatEvent to QuartersEconomy v1.0.0
org.bukkit.event.EventException
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
        at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:484) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
        at net.minecraft.server.v1_11_R1.PlayerConnection.chat(PlayerConnection.java:1276) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
        at net.minecraft.server.v1_11_R1.PlayerConnection.a(PlayerConnection.java:1214) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
        at net.minecraft.server.v1_11_R1.PacketPlayInChat$1.run(PacketPlayInChat.java:39) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.base/java.lang.Thread.run(Thread.java:830) [?:?]
Caused by: java.lang.IllegalAccessError: class retrofit2.converter.gson.GsonRequestBodyConverter tried to access private method 'com.google.gson.stream.JsonWriter com.google.gson.Gson.newJsonWriter(java.io.Writer)' (retrofit2.converter.gson.GsonRequestBodyConverter is in unnamed module of loader org.bukkit.plugin.java.PluginClassLoader @4e95987c; com.google.gson.Gson is in unnamed module of loader 'app')
        at retrofit2.converter.gson.GsonRequestBodyConverter.convert(GsonRequestBodyConverter.java:45) ~[?:?]
        at retrofit2.converter.gson.GsonRequestBodyConverter.convert(GsonRequestBodyConverter.java:30) ~[?:?]
        at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:412) ~[?:?]
        at retrofit2.RequestFactory.create(RequestFactory.java:117) ~[?:?]
        at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:192) ~[?:?]
        at retrofit2.OkHttpCall.execute(OkHttpCall.java:175) ~[?:?]
        at com.p3pi27.quarterseconomy.quarters.QuartersWrapper.executeAsync(QuartersWrapper.java:26) ~[?:?]
        at com.p3pi27.quarterseconomy.auth.AuthManager.validateTypedToken(AuthManager.java:108) ~[?:?]
        at com.p3pi27.quarterseconomy.auth.AuthManager.onPlayerChat(AuthManager.java:177) ~[?:?]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[?:?]
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:302) ~[spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
        ... 11 more

It seems when the Bukkit API calls the AsyncPlayerChatEvent (which then executes the function validateToken(), executing the executeAsync() function in another class, which at the moment just executes the request on the Main thread), Gson's newJsonWriter() function is blocked, since it comes from a different module...?

Any help is much appreciated. Thanks!

1 Answers1

1

I have no experience with Bukkit, but this error occurs because one class cannot access private method of another class loaded by different class loader:

java.lang.IllegalAccessError: class retrofit2.converter.gson.GsonRequestBodyConverter tried to access private method 'com.google.gson.stream.JsonWriter com.google.gson.Gson.newJsonWriter(java.io.Writer)' (retrofit2.converter.gson.GsonRequestBodyConverter is in unnamed module of loader org.bukkit.plugin.java.PluginClassLoader @4e95987c; com.google.gson.Gson is in unnamed module of loader 'app')


Try to load Gson library as part of the deployment to Bukkit, so that Retrofit and Gson are both loaded by the same class loader.

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • Do you know how I would do that? At the moment, the API library (containing retrofit and the retrofit gson converter) is in my build.gradle file, with the 'compile' configuration, and the jar task has the "from configurations.compile.collect...." line to include it in the final JAR file. I have also tried just copying and pasting the .java files into my current project, but the same error occurs. – graphicalcake95 Nov 14 '19 at 14:58