when a PropertyBatchUpdateException gets instantiated it does not pass the PropertyAccessExceptions as cause to its super (BeansException), instead storing it locally in propertyAccessExceptions:
|
/** |
|
* 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 java.base@21.0.5/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.base@21.0.5/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base@21.0.5/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base@21.0.5/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base@21.0.5/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
at java.base@21.0.5/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base@21.0.5/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base@21.0.5/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base@21.0.5/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base@21.0.5/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base@21.0.5/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at java.base@21.0.5/java.util.Optional.orElseGet(Optional.java:364)
at java.base@21.0.5/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:
|
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:
|
@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)
when a
PropertyBatchUpdateExceptiongets instantiated it does not pass thePropertyAccessExceptions ascauseto itssuper(BeansException), instead storing it locally inpropertyAccessExceptions:spring-framework/spring-beans/src/main/java/org/springframework/beans/PropertyBatchUpdateException.java
Lines 48 to 56 in a63c5ad
this makes sense since
propertyAccessExceptionsis a list whilecausecan only be a single exception.however, the output of this is really nondescript and does not contain the actual root cause:
as you can see it includes
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'elasticsearchOperations' threw exceptionwhich comes from its name:spring-framework/spring-beans/src/main/java/org/springframework/beans/MethodInvocationException.java
Line 44 in a63c5ad
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 byPropertyBatchUpdateException#toString:spring-framework/spring-beans/src/main/java/org/springframework/beans/PropertyBatchUpdateException.java
Lines 96 to 106 in a63c5ad
it seems that the standard
PropertyAccessException#toStringdoes not include thecause, so maybe that needs to be handled byPropertyBatchUpdateException#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)