-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Description
when a PropertyBatchUpdateException
gets instantiated it does not pass the PropertyAccessException
s as cause
to its super
(BeansException
), instead storing it locally in propertyAccessExceptions
:
Lines 48 to 56 in a63c5ad
/** | |
* Create a new PropertyBatchUpdateException. | |
* @param propertyAccessExceptions the List of PropertyAccessExceptions | |
*/ | |
public PropertyBatchUpdateException(PropertyAccessException[] propertyAccessExceptions) { | |
super(null, null); | |
Assert.notEmpty(propertyAccessExceptions, "At least 1 PropertyAccessException required"); | |
this.propertyAccessExceptions = propertyAccessExceptions; | |
} |
this makes sense since propertyAccessExceptions
is a list while cause
can only be a single exception.
however, the output of this is really nondescript and does not contain the actual root cause:
Error creating bean with name 'exampleRepository' defined in org.example.repository.exampleRepository defined in @EnableElasticsearchRepositories declared on OpenSearchConfiguration: Failed properties: Property 'elasticsearchOperations' threw exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exampleRepository' defined in org.example.repository.exampleRepository defined in @EnableElasticsearchRepositories declared on OpenSearchConfiguration: Failed properties: Property 'elasticsearchOperations' threw exception
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1746)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1460)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:346)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1149)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1121)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1056)
at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987)
at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
at app//org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
at app//org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
at app//org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1461)
at app//org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553)
at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
at app//org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
at app//org.springframework.test.context.bean.override.BeanOverrideTestExecutionListener.injectFields(BeanOverrideTestExecutionListener.java:93)
at app//org.springframework.test.context.bean.override.BeanOverrideTestExecutionListener.prepareTestInstance(BeanOverrideTestExecutionListener.java:64)
at app//org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
at app//org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:160)
at [email protected]/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at [email protected]/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at [email protected]/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at [email protected]/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at [email protected]/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
at [email protected]/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at [email protected]/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at [email protected]/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at [email protected]/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at [email protected]/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at [email protected]/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at [email protected]/java.util.Optional.orElseGet(Optional.java:364)
at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'elasticsearchOperations' threw exception
at app//org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:135)
at app//org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:79)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1743)
... 43 more
as you can see it includes PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'elasticsearchOperations' threw exception
which comes from its name:
spring-framework/spring-beans/src/main/java/org/springframework/beans/MethodInvocationException.java
Line 44 in a63c5ad
super(propertyChangeEvent, "Property '" + propertyChangeEvent.getPropertyName() + "' threw exception", cause); |
however it doesn't say what that exception (i.e. its cause
) is. it has a cause set (i checked with the debugger), it's just a matter of also printing it. i presume the formatting for printing is done by PropertyBatchUpdateException#toString
:
Lines 96 to 106 in a63c5ad
@Override | |
public String toString() { | |
StringBuilder sb = new StringBuilder(); | |
sb.append(getClass().getName()).append("; nested PropertyAccessExceptions ("); | |
sb.append(getExceptionCount()).append(") are:"); | |
for (int i = 0; i < this.propertyAccessExceptions.length; i++) { | |
sb.append('\n').append("PropertyAccessException ").append(i + 1).append(": "); | |
sb.append(this.propertyAccessExceptions[i]); | |
} | |
return sb.toString(); | |
} |
it seems that the standard
PropertyAccessException#toString
does not include the cause
, so maybe that needs to be handled by PropertyBatchUpdateException#toString
?
(i didn't create a minimum repro for this as i think the affected code is quite obvious from the callstacks & source links provided)