Issue
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.
Answered By - Jan Herzog