Spring Autowired Component is null in bean method

Viewed 447

I am trying to use an @Autowired variable in an @Configuration class, where a bean is created using @Bean in a method. However the component I need to create the bean with is null.

@Autowired
private JDAListener listener;

@Bean
public ShardManager shardManager() throws LoginException, IllegalArgumentException {
    DefaultShardManagerBuilder builder = DefaultShardManagerBuilder.createDefault(this.botToken)
            .enableIntents(GatewayIntent.GUILD_MEMBERS)
            .setStatus(OnlineStatus.IDLE)
            .setShardsTotal(this.totalShards)
            .addEventListeners(Arrays.asList(this.listener)); //throws Exception

    return builder.build();
}

The Exception I get is as follows:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'config': 
Unsatisfied dependency expressed through field 'shardManager'; nested exception is org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'shardManager' defined in class path resource [dev/teamnight/nightbot/Config.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: 
Failed to instantiate [net.dv8tion.jda.api.sharding.ShardManager]: Circular reference involving containing bean 'config' - consider declaring the factory method as static for independence from its containing instance. Factory method 'shardManager' threw exception; 
nested exception is java.lang.IllegalArgumentException: listeners may not be null
3 Answers

I assume the code snippet is a part of some kind of configuration (Something annotated with @Configuration or maybe even @SpringBootApplication).

In this case:

  1. Make JDAListener be managed by Spring container as well.
  2. Inject the instance of JDAListener bean into the shard manager by passing the parameter to the shardManager method

You will end up with the code that looks like this:

@Configuration
public class MyConfiguration {


  @Bean // now jda listener is managed by spring!
  public JDAListener jdaListener() {
     return new JDAListener();
  }

  @Bean // note the parameter to the method
  public ShardManager shardManager(JDAListener jdaListener) throws LoginException, IllegalArgumentException {
        DefaultShardManagerBuilder builder = 
              DefaultShardManagerBuilder.createDefault(this.botToken)
                 .enableIntents(GatewayIntent.GUILD_MEMBERS)
                 .setStatus(OnlineStatus.IDLE)
                 .setShardsTotal(this.totalShards)
                 .addEventListeners(Arrays.asList(jdaListener)); //throws Exception

    return builder.build();
 }
}

I think that you're facing this issue because Spring attempted to dependency inject the bean before it injected the listener. How about you try declare JdaListener as a bean as well?

Is JDAListener is marked as @Component/ @Service or something which tells the framework that it is suppose to be treated as a bean? Also, quickly check your component scan configuration.

Related