This is not a common problem with Cayenne. In fact this is the first time I see it happen in any environment. So Spigot is special in this respect. I found this link: https://bukkit.fandom.com/wiki/Using_External_Libraries_with_Plugins <https://bukkit.fandom.com/wiki/Using_External_Libraries_with_Plugins> It doesn't answer the question, but provides some hints. So how do you package your own code and third-party dependencies like Cayenne for Spigot/Bukkit? Do you use "shading"?
Andrus > On Mar 23, 2022, at 4:51 PM, Stefan Stegic <stefanste...@gmail.com> wrote: > > Hi, > > Thanks for your quick responses! I'm using version 4.1.1. > Right, so you're saying Spigot is somehow blocking the execution of said > code, or it's circumventing it somehow so that those steps of > initialization are never actually executed? Also, you mean that it's a > common problem with Cayenne or with Spigot and other jars? > > How would we go about understanding how the Spigot classpath works? It > might help to know that the plugin API is called Bukkit, so Spigot is kind > of the parent entity (it's a customized Minecraft server, while Bukkit is > the interface for plugins, as I've come to understand). It's source code > should be here: > https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse . > > On Wed, Mar 23, 2022 at 4:33 PM Andrus Adamchik <aadamc...@gmail.com> wrote: > >> The bootstrap code is as vanilla as it can get: >> >>>> ServerRuntime cayenneRuntime = ServerRuntime.builder() >>>> .addConfig("cayenne-project.xml") >>>> .build(); >> >> Missing ObjectContextFactory means ServerModule is not loaded in the >> environment. Since 4.1 (BTW, which version of Cayenne are we talking >> about?), ServerModule is loaded by processing >> "META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider" >> files from the classpath jars. So there's something about Spigot's >> classpath that prevents this code in ModuleLoader from returning proper >> resources: >> >> for (ModuleProvider provider : ServiceLoader.load(providerClass)) { ... } >> >> We need to understand how Spigot classpath works. Cursory Googling shows >> that this is a common problem, just don't immediately see a solution. >> >> Andrus >> >> >>> On Mar 23, 2022, at 4:03 PM, Andrus Adamchik <aadamc...@gmail.com> >> wrote: >>> >>> Actually the stack shows that there's already an instance of Cayenne >> runtime available to the code, but the runtime is in a bad state (not clear >> why). So thread binding should not be required. >>> >>> Andrus >>> >>> >>>> On Mar 23, 2022, at 4:00 PM, John Huss <johnth...@gmail.com> wrote: >>>> >>>> You have to bind the DI injector to the thread (and unbind it later): >>>> >>>> CayenneRuntime.*bindThreadInjector*(cayenneRuntime.getInjector()); >>>> >>>> If you are using servlets, then CayenneFilter will do this for you. >>>> Otherwise you can bind it at the start of a request and unbind it at the >>>> end. >>>> >>>> On Wed, Mar 23, 2022 at 9:10 AM Stefan Stegic <stefanste...@gmail.com> >>>> wrote: >>>> >>>>> Hi Andrus, >>>>> >>>>> Of course: >>>>> >>>>> org.apache.cayenne.di.DIRuntimeException: DI container has no binding >> for >>>>> key <BindingKey: org.apache.cayenne.configuration.ObjectContextFactory> >>>>> at >>>>> >>>>> >> org.apache.cayenne.di.spi.DefaultInjector.getProvider(DefaultInjector.java:158) >>>>> ~[?:?] >>>>> at >>>>> >>>>> >> org.apache.cayenne.di.spi.DefaultInjector.getProvider(DefaultInjector.java:144) >>>>> ~[?:?] >>>>> at >>>>> >>>>> >> org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:134) >>>>> ~[?:?] >>>>> at >>>>> >>>>> >> org.apache.cayenne.configuration.CayenneRuntime.newContext(CayenneRuntime.java:124) >>>>> ~[?:?] >>>>> at >>>>> >>>>> >> io.github.phuskus.firstspigotplugin.StatisticsController.reportPlayerConnectionEvent(StatisticsController.java:20) >>>>> ~[?:?] >>>>> at >>>>> >>>>> >> io.github.phuskus.firstspigotplugin.FirstSpigotPlugin.onEnable(FirstSpigotPlugin.java:29) >>>>> ~[?:?] >>>>> at >>>>> org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264) >>>>> ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?] >>>>> at >>>>> >>>>> >> org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:342) >>>>> ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?] >>>>> at >>>>> >>>>> >> org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:480) >>>>> ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?] >>>>> at >>>>> >>>>> >> org.bukkit.craftbukkit.v1_18_R1.CraftServer.enablePlugin(CraftServer.java:521) >>>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499] >>>>> at >>>>> >>>>> >> org.bukkit.craftbukkit.v1_18_R1.CraftServer.enablePlugins(CraftServer.java:435) >>>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499] >>>>> at >>>>> >> net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:612) >>>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499] >>>>> at >>>>> >> net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:414) >>>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499] >>>>> at >>>>> >> net.minecraft.server.dedicated.DedicatedServer.e(DedicatedServer.java:262) >>>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499] >>>>> at >> net.minecraft.server.MinecraftServer.w(MinecraftServer.java:994) >>>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499] >>>>> at >>>>> net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:304) >>>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499] >>>>> at java.lang.Thread.run(Thread.java:833) [?:?] >>>>> >>>>> On Wed, Mar 23, 2022 at 11:49 AM Andrus Adamchik <aadamc...@gmail.com> >>>>> wrote: >>>>> >>>>>> Hi Stefan, >>>>>> >>>>>> Could you include a full stack trace please? >>>>>> >>>>>> Thanks, >>>>>> Andrus >>>>>> >>>>>>> On Mar 23, 2022, at 1:04 AM, Stefan Stegic <stefanste...@gmail.com> >>>>>> wrote: >>>>>>> >>>>>>> Hi, >>>>>>> >>>>>>> >>>>>>> First some context: I'm working on a custom Minecraft server (Spigot) >>>>>>> plugin. It's just a JAR that you export and place somewhere in the >>>>>> server's >>>>>>> folder structure. >>>>>>> >>>>>>> I wrote a simple insert query via Cayenne's API. It works when I run >>>>> the >>>>>>> example JAR directly via executing Main from the command line (java >> -cp >>>>>>> myPlugin.jar path.to.Main), but it fails with the following error >> when >>>>>>> executed by the server in my plugin's OnEnable lifecycle hook: >>>>>>> >>>>>>> org.apache.cayenne.di.DIRuntimeException: DI container has no binding >>>>> for >>>>>>> key <BindingKey: >> org.apache.cayenne.configuration.ObjectContextFactory> >>>>>>> >>>>>>> >>>>>>> My initial theory was that it's being executed from a different >> thread, >>>>>> so >>>>>>> the DI system might not have access to that dependency for some >> reason, >>>>>> but >>>>>>> it seems like the server executes this lifecycle hook from the main >>>>>> thread >>>>>>> as well (though they've named the thread "Server thread", and I don't >>>>>> know >>>>>>> how to check if it's the main thread for sure). Not sure if this is a >>>>>>> promising direction to pursue, but I got the hunch by looking at the >>>>>>> threadInjector bits of Cayenne's DI container docs. >>>>>>> >>>>>>> My example looks like this: >>>>>>> >>>>>>> ServerRuntime cayenneRuntime = ServerRuntime.builder() >>>>>>> .addConfig("cayenne-project.xml") >>>>>>> .build();ObjectContext ctx = >>>>> cayenneRuntime.newContext(); >>>>>>> PlayerConnectionEvent newEvent = >>>>>>> ctx.newObject(PlayerConnectionEvent.class); >>>>>>> newEvent.setEventType(eType); >>>>>>> newEvent.setPlayerName(playerName); >>>>>>> newEvent.setIpAddress(ipAddress); >>>>>>> newEvent.setTimestampUnixSeconds(unixSeconds); >>>>>>> >>>>>>> ctx.commitChanges(); >>>>>>> >>>>>>> Some help would be greatly appreciated, thanks in advance! >>>>>>> -- >>>>>>> S poštovanjem, >>>>>>> *Stefan Stegić* >>>>>> >>>>>> >>>>> >>>>> -- >>>>> S poštovanjem, >>>>> *Stefan Stegić* >>>>> >>> >> >> > > -- > S poštovanjem, > *Stefan Stegić*