Nightloewe
Nightloewe

Reputation: 1098

NullPointerException during bean creation in Spring

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

Answers (2)

Ankush Sharma
Ankush Sharma

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:-

  1. Either you can remove the config from the HelpProvider and try to redesign it.
  2. Use @Lazy on Config in HelpProvider which will load this dependency on object instantiation. Will suggest it as a last resort.

Upvotes: 0

shinjw
shinjw

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.

General Dependency Injection Debugging

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.

  1. Configuration files - Are these being loaded in correctly. Is your component scanning recently disabled?
  2. Do your Components have the necessary @Component and or @Service/@Controller/@Repository annotations?

The Likely Root Problem - Circular Reference - BeanInstantiationException

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.

What you should do

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.

What you shouldn't do

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

Related Questions