Search code examples
javaspringbukkit

Spring @ComponentScan does not scan


I have set up a Spring Project (Not Boot). I've done that to use it in a minecraft (paper) plugin. The problem I'm facing now describes as the follwing: I have an BukkitSpringApplication class and a Subserver class (which is the main class of the bukkit plugin). The Subserver class contains an onEnable() Method which is called if the plugin starts up. At that point I want to start my Spring Application too better to say: I want to scann my packages for components. I think i've done that correctly, but the only result I'm getting in the console is that there are 5 beans of which 4 are spring related beans and the last one the Application bean (BukkitSpringApplication).

Console:

[15:35:36] [Server thread/INFO]: [Subserver-bukkit] Enabling Subserver-bukkit v1.0*
[15:35:36] [Server thread/INFO]: 5
[15:35:36] [Server thread/INFO]: [Subserver-bukkit] org.springframework.context.annotation.internalConfigurationAnnotationProcessor
[15:35:36] [Server thread/INFO]: [Subserver-bukkit] org.springframework.context.annotation.internalAutowiredAnnotationProcessor
[15:35:36] [Server thread/INFO]: [Subserver-bukkit] org.springframework.context.event.internalEventListenerProcessor
[15:35:36] [Server thread/INFO]: [Subserver-bukkit] org.springframework.context.event.internalEventListenerFactory
[15:35:36] [Server thread/INFO]: [Subserver-bukkit] bukkitSpringApplication
[15:35:36] [Server thread/ERROR]: Error occurred while enabling Subserver-bukkit v1.0 (Is it up to date?)
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'de.nebelniek.BukkitConfiguration' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351) ~[bukkit-1.0-SNAPSHOT-shaded.jar:?]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342) ~[bukkit-1.0-SNAPSHOT-shaded.jar:?]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1172) ~[bukkit-1.0-SNAPSHOT-shaded.jar:?]
    at de.nebelniek.Subserver.onEnable(Subserver.java:22) ~[bukkit-1.0-SNAPSHOT-shaded.jar:?]
    at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264) ~[patched_1.17.1.jar:git-Purpur-1418]
    at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:370) ~[patched_1.17.1.jar:git-Purpur-1418]
    at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:500) ~[patched_1.17.1.jar:git-Purpur-1418]
    at org.bukkit.craftbukkit.v1_17_R1.CraftServer.enablePlugin(CraftServer.java:561) ~[patched_1.17.1.jar:git-Purpur-1418]
    at org.bukkit.craftbukkit.v1_17_R1.CraftServer.enablePlugins(CraftServer.java:475) ~[patched_1.17.1.jar:git-Purpur-1418]
    at net.minecraft.server.MinecraftServer.loadWorld(MinecraftServer.java:733) ~[patched_1.17.1.jar:git-Purpur-1418]
    at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:353) ~[patched_1.17.1.jar:git-Purpur-1418]
    at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1230) ~[patched_1.17.1.jar:git-Purpur-1418]
    at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:322) ~[patched_1.17.1.jar:git-Purpur-1418]
    at java.lang.Thread.run(Thread.java:831) ~[?:?]

My Subserver class:

public class Subserver extends JavaPlugin {

    private AnnotationConfigApplicationContext context;

    @SneakyThrows
    @Override
    public void onEnable() {
        context = new AnnotationConfigApplicationContext(BukkitSpringApplication.class);
        System.out.println(context.getBeanDefinitionCount());
        for (String beanName : context.getBeanDefinitionNames()) {
            System.out.println(beanName);
        }
        BukkitConfiguration bukkitConfiguration = context.getBean(BukkitConfiguration.class);
        bukkitConfiguration.startMinecraftPlugin(context, this);
        context.registerShutdownHook();
    }

    @Override
    public void onDisable() {
        context.close();
        context = null;
    }
}
@Configuration
@ComponentScan(basePackages = "de.nebelniek")
public class BukkitSpringApplication {

}

My BukkitConfiguration :

package de.nebelniek;

@Getter
@Configuration
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class BukkitConfiguration {

    private final ApplicationEventPublisher eventPublisher;

    private final HomeController homeController;
    private final VerifyController verifyController;

    private CredentialManager credentialManager;

    public void startMinecraftPlugin(ApplicationContext context, JavaPlugin plugin) {
        this.eventPublisher.publishEvent(new BukkitPluginEnableEvent(context, plugin));
        this.homeController.setupRoutes();
        this.verifyController.setupRoutes();
    }

    @Setter
    private PaperCommandManager commandManager;

}

So do anyone know what I've doen wrong? Thanks for your help! <3


Solution

  • I've managed it to solve this issue. The problem here is, that spring uses the default ClassLoader but, since I'm using bukkit, the classes get loaded by a PluginClassLoader.

    So how do I get the PluginClassLoader?

    In a class extending JavaPlugin you can easily invoke getClassLoader() to get the PluginClassLoader.

    Now how do I set it to be the one spring is using?

    Just throw this in your onEnable() and you'll be good.

            Thread.currentThread().setContextClassLoader(getClassLoader());
    

    Anyways, thanks for your help.