I have an issue where the autowiring is failing after an application context restart, calls appear to be being made on the cglib proxy directly, rather than to the target object, resulting in a null pointer exception.
I'm using spring boot 3.5.0 ( Spring 6.2.7 ). This was not happening with spring 6.2.3
The basic shape of the code below is that we have a TaskStore component which autowires a TemplateCache component, which autowires a repository interface. Within 'afterPropertiesSet' in the cache we read a table from the database ( then all operations on that table go through the cache )
After a restart the TemplateCache is created normally and the table is read, but when the store later calls a get method on the cache ( also from an afterPropertiesSet method ) we get this situation, where the 'this' pointer is to the proxy rather than the target
The call stack is:
The errors are:
2025-05-30 11:00:49,913 ERROR o.s.b.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'alertingController': Unsatisfied dependency expressed through field 'taskStore': Error creating bean with name 'taskStore' defined in file [...\TaskStore.class]: Cannot invoke "java.util.concurrent.ConcurrentMap.get(Object)" because "this.cache" is null
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:788)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:768)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:146)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:509)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1459)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:606)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:149)
at xx.Application.lambda$restart$0(Application.java:45)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'taskStore' defined in file [...\TaskStore.class]: Cannot invoke "java.util.concurrent.ConcurrentMap.get(Object)" because "this.cache" is null
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1826)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1682)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1628)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:785)
... 22 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.concurrent.ConcurrentMap.get(Object)" because "this.cache" is null
at xx.TemplateCache.findByUid(TemplateCache.java:42)
at xx.persist.TaskStore.afterPropertiesSet(TaskStore.java:46)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1873)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1822)
And the restart code - after Baeldung :
public static void restart() {
LOG.info("Restart called");
ApplicationArguments args = context.getBean(ApplicationArguments.class);
Thread restartThread = new Thread(() -> {
context.close();
SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);
context = builder.run(args.getSourceArgs());
});
restartThread.setDaemon(false);
restartThread.start();
}
I am out of my depth here, but I will try to work up a minimal test case to reproduce.