Solved When class implements Listener Spring tried to find file

Discussion in 'Spigot Plugin Development' started by EwrsPlay, Feb 24, 2020.

  1. I made a Bean UserService, I need to implement the Listener interface (Bukkit API) in it, but it needs to find it as a file. Why? If you remove the Listener from the implementation, then everything is fine.

    What happens when context.refresh();
    https://pastebin.com/dTWNGgss (Deleted something)

    Code (Text):

    context = new ClassPathXmlApplicationContext();
       context.setClassLoader(I728Lib.class.getClassLoader());
       context.setConfigLocation("spring.xml");
       context.refresh();
     
     
  2. Ist that really a good decision to junk a spring boot application into a plugin? No it isn't.
     
  3. I use spring context
     
    #3 EwrsPlay, Feb 24, 2020
    Last edited: Feb 24, 2020
  4. By the way, it works great from 1.12.2. The error is specifically at 1.15.2
     
  5. Have you even bother reading the exception?

    Failed to parse configuration class [UserService]; nested exception is java.io.FileNotFoundException: class path resource
     
  6. In your opinion should I stuff bukkit api myself in jar?
    At the same time, on 1.12.2 everything works. As for me, this is clearly a classloader related error
     
  7. After doing a little test, I had a question. Bukkit 1.12.2 adds its api to Classloader?

    on 1.12.2 it returns a result
    on 1.15.2 it returns null
    Code (Text):
    getClass().getClassLoader().getResourceAsStream("org/bukkit/event/Listener.class");
     
  8. I would strongly suggest you to learn java, before attempting to blindly implement Spring into your plugin.
     
    • Funny Funny x 1
    • Optimistic Optimistic x 1
  9. I ran into the same issue. In 1.13.x and 1.14.x and 1.15 it works for me to use spring by setting the contextClassLoader to be <plugin>.getClassLoader() among other things, but this seems to have broken in 1.15.1 and later.

    Did spigot change the way that the classloader works in 1.15.1+?

    Here is my code:
    Code (Text):
    public class HeadsPlugin extends JavaPlugin {

       ...

        @Override
        public void onLoad() {
            springClassLoaders = new ArrayList<>();
            getLogger().info("Added class loader to HeadsPlugin springClassLoaders");
            springClassLoaders.add(getClassLoader());
        }

        @Override
        public void onEnable() {
            // configure the class loader and run the spring application
            defaultClassLoader = Thread.currentThread().getContextClassLoader();
            ClassLoader classLoader = new CompoundClassLoader(springClassLoaders);
            Thread.currentThread().setContextClassLoader(classLoader);
            ResourceLoader loader = new DefaultResourceLoader(classLoader);
            SpringApplication application = new SpringApplication(loader, Application.class);
            application.addInitializers(new SpringSpigotInitializer(this));
            springContext = application.run();
        }

        ...

    }
     
    #11 cc007, Mar 11, 2020
    Last edited: Mar 12, 2020
  10. I looked through the commits in Bukkit and CraftBukkit, but I couldn't find anything related to classloaders in there. I might have missed it though...

    @md_5 do you know what could cause certain Bukkit classes not to be found in 1.15.1, where in 1.15 it works as it should? Asking you since you were involved with most of the commits between these versions.
     
  11. 1. You don't randomly ping the administrator.
    2. You dont just hijack a similar thread, create a new one and explain your problem there.
     
  12. 1. I didn't randomly ping the admin. I specifically pinged here because this is a niche issue with the classloader and I saw that md_5 committed and/or reviewed these commits, and therefore be the onlyone who would know the answer.
    2. I posted in this thread because after reading it fully, I believe it has the same underlying issue: setting a spring context causes a ClassDefNotFounfException for org.bukkit.event.Listener. I tried to add extra context and not fragment forum threads which are related to the same issue, but if people think I need to create a new thread instead, I will. No problem.
     
    #14 cc007, Mar 12, 2020
    Last edited: Mar 12, 2020
  13. @EwrsPlay Have you tried using a org.switchyard.common.type.CompoundClassLoader and add the
    Thread.currentThread().getContextClassLoader(); to this classloader as well as getClassloader from the JavaPlugin? That seemed to be what fixed it for me in 1.15.1 and 1.15.2.
     
    • Winner Winner x 1
  14. Thank you)