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ć*