Reputation: 1098
I'm receiving a NullPointerException in a method with the Annotation @Bean
, but before I never got this NullPointerException there:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [dev.teamnight.command.CommandFramework]: Circular reference involving containing bean 'config' - consider declaring the factory method as static for independence from its containing instance. Factory method 'commandFramework' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 68 common frames omitted
Caused by: java.lang.NullPointerException: null
at dev.teamnight.nightbot.Config.commandFramework(Config.java:84) ~[classes/:na]
at dev.teamnight.nightbot.Config$$EnhancerBySpringCGLIB$$2d4937ec.CGLIB$commandFramework$3(<generated>) ~[classes/:na]
at dev.teamnight.nightbot.Config$$EnhancerBySpringCGLIB$$2d4937ec$$FastClassBySpringCGLIB$$3fbdfefd.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at dev.teamnight.nightbot.Config$$EnhancerBySpringCGLIB$$2d4937ec.commandFramework(<generated>) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 69 common frames omitted
The code of the file causing the Exception:
@Configuration
@PropertySource("file:bot.properties")
public class Config {
@Autowired
private ShardManager shardManager;
@Autowired
private PermissionProvider permissionProvider;
@Autowired
private LanguageProvider languageProvider;
@Autowired
private PrefixProvider prefixProvider;
@Autowired
private HelpProvider helpProvider;
@Bean
public ShardManager shardManager() throws LoginException, IllegalArgumentException {
DefaultShardManagerBuilder builder = DefaultShardManagerBuilder.createDefault(this.botToken)
.enableIntents(GatewayIntent.GUILD_MEMBERS)
.setMemberCachePolicy(MemberCachePolicy.ALL)
.setStatus(OnlineStatus.IDLE)
.setShardsTotal(this.totalShards)
.addEventListeners(Arrays.asList(this.jdaListener()));
return builder.build();
}
@Bean
public CommandFramework commandFramework() {
Logger log = LogManager.getLogger();
//Line causing the error below!
log.error("Name of helpProvider: " + this.helpProvider.getClass().getCanonicalName());
return new FrameworkBuilder()
.addOwners(Arrays.stream(this.ownerIds).filter(ownerId -> ownerId.matches("^(\\d)+$")).map(ownerId -> Long.parseLong(ownerId)).collect(Collectors.toList()))
.setLogger(NightBot.logger())
.allowBots(false)
.allowDM(false)
.allowMention(true)
.allowRainbowColors(true)
.withPrefixProvider(this.prefixProvider)
.withLanguageProvider(this.languageProvider)
.withPermissionProvider(this.permissionProvider)
.withHelpProvider(this.helpProvider)
.withCustomArgumentProcessor(new NamedArgumentProcessor())
.registerClient(this.shardManager)
.build();
}
}
As I said, before the code fully worked, and I changed nothing on the Config.java file, so this error is confusing me as hell.
Upvotes: 3
Views: 9644
Reputation: 140
The error you are getting is most probably because you have a cyclic dependency in your project. And since you are getting it in commandFramework method as illustrated in error it is because of the HelpProvider class in which you are using the Config class again.
So when spring is creating a bean of Config it has to create a bean of HelpProvider which in terms wants to create a bean of Config(Autowired in HelpProvider) and leads to a never ending cycle giving the error. Also check if HelpProvider has the @component annotataion.
Config -> HelpProvider -> Config -> HelpProvider -> Config .............
Solution:-
Upvotes: 0
Reputation: 3431
You are seeing this NullPointerException
because the autowired HelperProvider
not being injected in.
You are attempting to call .getClass()
on a null object.
Just want to add a quick basic mentions, since the main answer to this question has to make some assumption on your codebase. There are several things that you want to check when dependency injection fails.
Components
have the necessary @Component
and or @Service/@Controller/@Repository
annotations?There is also a mention of a circular reference in your stacktrace which is likely what is causing the problem.
Caused by: org.springframework.beans.BeanInstantiationException: Circular reference involving containing bean 'config' - consider declaring the factory method as static for independence from its containing instance. Factory method 'commandFramework' threw exception; nested exception is java.lang.NullPointerException
Since you received this error message, you have introduced a circular reference. This means... that a component relies on a component which relies on that component.
For example:
@Component
class HelperProvider {
@Autowired
Config config;
}
and
@Configuration
class Config {
@Autowired
HelperProvider helperProvider
}
This pattern will stump the spring framework because they rely on each other to load each component up. It can happen if you introduce a dependency further down the line. Say HelperProvider requires HelperHelperProvider which requires Config.
You will want to check for any new injections of Config
or CommandFramework
in your recent edits.
You will want to redesign your configuration to break it's reliance on the HelperProvider
. Doing this can resolve a lot of headaches in your future.
It's possible to lazyload the component or configuration with @Lazy
annotation. That way the bean is only instantiated upon invocation. It's recommended if you want to learn more nuances in booting up the Spring ApplicationContext
, but it will become a nightmare to maintain down the road.
Upvotes: 1