2

I am trying to list all the managed Components in a Spring Boot application using a ListableBeanFactory interface as illustrated in How to Get All Spring-Managed Beans?

@SpringBootApplication
public class Application {
    private static ApplicationContext applicationContext;

    public static void main(String[] args) {
        applicationContext = SpringApplication.run(Application.class, args);
        displayAllBeans();
    }

    public static void displayAllBeans() {
        String[] allBeanNames = applicationContext.getBeanDefinitionNames();
        for(String beanName : allBeanNames) {
            System.out.println(beanName);
        }
    }
}

When running the application I get the following Exception indicating that the applicationContext object is null

Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.lang.NullPointerException
    at mygroup.myapp.displayAllBeans(myapp.java:18)
    at mygroup.myapp.main(myapp.java:14)
    ... 5 more

What am I missing? Thanks in advance

UPDATE:

The code from the example works as expected. There was a mistake in my code that prevented the applicationContext variable to be set up correctly.

j.xavier.atero
  • 506
  • 2
  • 10
  • 25
  • Which line is throwing the exception, i.e. which line is line `18`? – Turing85 Sep 07 '19 at 22:33
  • 2
    @j.xavier.atero Check official example: [Spring Boot Guide](https://github.com/spring-guides/gs-spring-boot/blob/master/complete/src/main/java/hello/Application.java) – jpact Sep 07 '19 at 22:34
  • @Turing85 line 18 is `String[] allBeanNames = applicationContext.getBeanDefinitionNames();` but `applicationContext` is `null` when that line is reached – j.xavier.atero Sep 07 '19 at 22:35
  • @jpact I cheked the official example that you indicate and it works, thanks! – j.xavier.atero Sep 07 '19 at 22:39
  • @j.xavier.atero glad it helps! I wrote some additional information to answer below. – jpact Sep 07 '19 at 23:08

1 Answers1

3

I think the problem is that the ApplicationContext instance was created by main thread, but then, for whatever reason, it was accessed by restartedMain thread.

As applicationContext attribute is not synchronized, nor volatile, the restartedMain thread accessed the stale data - thats why java.lang.NullPointerException.

To print out all of beans managed by Spring, you can use example from offical sources.

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {
            System.out.println("Let's inspect the beans provided by Spring Boot:");
            String[] beanNames = ctx.getBeanDefinitionNames();
            Arrays.sort(beanNames);
            for (String beanName : beanNames) {
                System.out.println(beanName);
            }

        };
    }
}
jpact
  • 1,042
  • 10
  • 23
  • adding to the response ... The `restartedMain` thread is generated by devtools [SpringBoot app starts multiple times ...](https://stackoverflow.com/questions/38635451/springboot-app-starts-multiple-times-and-disconnects-from-logstash). With devtools disabled the "only" running thread is `main`, executing the application in that scenario `applicationContext` is still `null` – j.xavier.atero Sep 08 '19 at 12:40