0

I am using a third-party package in my spring boot app. This one to be specific. This package has a method that creates a bean when the application starts. The bean is only created successfully if this package is able to talk to nats service. In most cases, this all works fine. The remote server is available, the bean is created, my spring boot apps boots up correctly.

But there are some edge cases when remote nats servers might not be up. This causes my spring boot app to fail to start as the above function throws BeanCreationException

How can I avoid this i.e avoid my spring app boot failure due to this exception when the nats server is not up?

Note: It is fine for my spring app/business logic to be up and running if this bean (connections to nats service) is not available.

Specific Exception :

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'natsConnection' defined in class path resource [io/nats/spring/boot/autoconfigure/NatsAutoConfiguration.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.nats.client.Connection]:
Factory method 'natsConnection' threw exception; nested exception is java.io.IOException: Unable to connect to NATS server.\n\tat org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655)\n\tat org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:635)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)\n\tat org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)\n\tat org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)\n\tat 
java_doctor_101
  • 3,287
  • 4
  • 46
  • 78
  • we have a docker-compose file to spin up services we depend on, since we have this problem in a lot of places: even our db migrations need a bean to talk to a broker to "lock" migrations in case multiple nodes would try to run db migrations. – Dave Ankin Dec 28 '20 at 00:52
  • 1
    You have 3k reputation, you know the drill: Please help other people to help you by providing information like at least exception call stack, aspects (especially pointcuts used). Both are relevant here as you have tagged the question _spring-aop_. – kriegaex Dec 28 '20 at 01:56

1 Answers1

0

The bean natsConnection is created by auto-configuration and annotated with @ConditionalOnMissingBean. Such beans are instantiated after your own beans.

You can create your own bean of this type, io.nats.client.Connection, and register it as natsConnection. This bean should have no own logic. When called for the first time, it should create a worker instance via NatsAutoConfiguration.natsConnection(...) and then delegate all calls to it.

Because of @ConditionalOnMissingBean the default bean from the NATS library will not be instantiated and only your bean will be created.

mentallurg
  • 4,967
  • 5
  • 28
  • 36
  • Hmm.. but won't spring call the library to create auto configuration bean after my custom bean? I am wondering if that would cause some sort of duplication? – java_doctor_101 Dec 28 '20 at 03:19
  • @nitinsh99: I have updated the answer. Because of `@ConditionalOnMissingBean` only your bean will be crated and the default one will not. – mentallurg Dec 28 '20 at 03:29