I think I may have figured it out! I switched to MongoDB with Morphia ODM and had the same problem: works when I run it through main, but throws a ClassNotFound when ran by Spigot. Morphia couldn't locate my entity classes package via its path and I solved it by supplying the class loader of the calling class like so:
MapperOptions mapperOptions = MapperOptions.builder().classLoader( > *this.getClass().getClassLoader()*).build(); > datastore = Morphia.createDatastore(MongoClients.create(connectionUri), > dbName, mapperOptions); > datastore.getMapper().mapPackage("path.to.my.models.package"); Could there be a similar problem with Cayenne? Is there a way to change the class loader before initialization in a similar matter? On Wed, Mar 23, 2022 at 5:53 PM Stefan Stegic <stefanste...@gmail.com> wrote: > Yup, it's in there: > > ################################################################## > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > # distributed with this work for additional information > # regarding copyright ownership. The ASF licenses this file > # to you under the Apache License, Version 2.0 (the > # "License"); you may not use this file except in compliance > # with the License. You may obtain a copy of the License at > # > # http://www.apache.org/licenses/LICENSE-2.0 > # > # Unless required by applicable law or agreed to in writing, > # software distributed under the License is distributed on an > # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > # KIND, either express or implied. See the License for the > # specific language governing permissions and limitations > # under the License. > ################################################################## > > org.apache.cayenne.configuration.server.MainCayenneServerModuleProvider > > On Wed, Mar 23, 2022 at 5:47 PM Andrus Adamchik <aadamc...@gmail.com> > wrote: > >> Ok, shading can be tricky. Do you have this file inside the shaded jar: >> >> >> >> "META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider" >> >> And if you do, can you check the contents of it? It is a simple text >> file, so once you extract it form the jar, you can check it in any text >> editor. >> >> Andrus >> >> >> >> > On Mar 23, 2022, at 5:26 PM, Stefan Stegic <stefanste...@gmail.com> >> wrote: >> > >> > Ok, just tried maven-shade-plugin, but no luck - still the same >> error... It >> > seems that the shading is working as expected: when I run maven package, >> > the output jar really has cayenne's stuff in there, but DI is still >> failing >> > when I copy the plugin into the server and start it. >> > >> > Michael, in response to your question: >> > >> >> Have you tried updating your "java -cp myPlugin.jar path.to.Main" >> command >> >> to have more classpaths? >> > >> > >> > When I run Main, it works, so that's not the problem. The problem arises >> > when my plugin is called by Spigot, the custom Minecraft server I'm >> writing >> > the plugin for. >> > >> > On Wed, Mar 23, 2022 at 5:20 PM Stefan Stegic <stefanste...@gmail.com> >> > wrote: >> > >> >> Hi Michael, >> >> >> >> Oh, I wasn't aware, thanks. Here's the screenshot from my last e-mail: >> >> https://imgur.com/QJoBGAV . >> >> Right, I'll give maven-shade-plugin a try now and check if it works >> that >> >> way, thanks. >> >> >> >> On Wed, Mar 23, 2022 at 5:18 PM Michael Gentry <blackn...@gmail.com> >> >> wrote: >> >> >> >>> If you aren't using a shaded JAR (which merges all JARs into a single >> >>> JAR), >> >>> then you'll need more JARs listed on your Java command. >> >>> >> >>> >> >>> On Wed, Mar 23, 2022 at 12:16 PM Stefan Stegic < >> stefanste...@gmail.com> >> >>> wrote: >> >>> >> >>>> PS: I'm not using maven-shade (just opened the link you sent) >> >>>> >> >>>> On Wed, Mar 23, 2022 at 5:10 PM Stefan Stegic < >> stefanste...@gmail.com> >> >>>> wrote: >> >>>> >> >>>>> My knowledge of Java is not so deep, so excuse stupid questions - if >> >>> any. >> >>>>> I believe I am using shading because I'm exporting dependencies >> into my >> >>>>> JAR. IntelliJ does this for me in the build process by publishing >> the >> >>> JAR >> >>>>> as an artifact. All I did was specify which dependencies I want to >> >>> package >> >>>>> in there like this: >> >>>>> >> >>>>> [image: image.png] >> >>>>> >> >>>>> So, I build the project, grab the published JAR artifact and put the >> >>> file >> >>>>> in the plugins folder of the Spigot server. I then run the Server >> and >> >>> it >> >>>>> tries to load each plugin JAR that's in there. That's when each of >> the >> >>>>> onEnable methods are called, including that of my plugin >> >>>>> (FirstSpigotPlugin). The example code that creates the >> CayenneRuntime >> >>> is in >> >>>>> my onEnable method. >> >>>>> >> >>>>> Should I be packaging these dependencies differently then? >> >>>>> >> >>>>> On Wed, Mar 23, 2022 at 4:56 PM Andrus Adamchik < >> aadamc...@gmail.com> >> >>>>> wrote: >> >>>>> >> >>>>>> 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ć* >> >>>>>> >> >>>>>> >> >>>>> >> >>>>> -- >> >>>>> S poštovanjem, >> >>>>> *Stefan Stegić* >> >>>>> >> >>>> >> >>>> >> >>>> -- >> >>>> S poštovanjem, >> >>>> *Stefan Stegić* >> >>>> >> >>> >> >> >> >> >> >> -- >> >> S poštovanjem, >> >> *Stefan Stegić* >> >> >> > >> > >> > -- >> > S poštovanjem, >> > *Stefan Stegić* >> >> > > -- > S poštovanjem, > *Stefan Stegić* > -- S poštovanjem, *Stefan Stegić*