spring-framework icon indicating copy to clipboard operation
spring-framework copied to clipboard

Problem after context restart

Open paulwoods222 opened this issue 6 months ago • 0 comments

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

Image

The call stack is:

Image

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.

paulwoods222 avatar May 30 '25 10:05 paulwoods222