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

Reply via email to