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

Reply via email to