Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE thrown for nonexistent default-destroy-method in XML config #30301

Closed
edfeff opened this issue Apr 7, 2023 · 3 comments
Closed

NPE thrown for nonexistent default-destroy-method in XML config #30301

edfeff opened this issue Apr 7, 2023 · 3 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Milestone

Comments

@edfeff
Copy link
Contributor

edfeff commented Apr 7, 2023

Affects: v6.0.7


When I configure the default-destroy-method in XML config and there is a bean that does not have a destroy method, a NullPointerException is thrown when closing the ApplicationContext.

Example Config and Code

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd"
  default-init-method="myInit"
  default-destroy-method="myDestroy">

  <bean id="a" class="com.wpp.core.c1.s1_6._3.AInit"/>
  <bean id="b" class="com.wpp.core.c1.s1_6._3.BDestroy"/>

</beans>
package com.wpp.core.c1.s1_6._3;
public class AInit {
  public void myInit() {
    System.out.println("A myInit");
  }
}
package com.wpp.core.c1.s1_6._3;
public class BDestroy {
  public void myDestroy() {
    System.out.println("B myDestroy");
  }
}
package com.wpp.core.c1.s1_6._3;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DefaultInitAndDestroyDemo {
  public static void main(String[] args) {
    var context = new ClassPathXmlApplicationContext("com/wpp/core/c1/s1_6/_3/DefaultInitAndDestroyDemo.xml");
    context.close();
  }
}

Exception

09:59:03.853 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext -- Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@880ec60
09:59:04.048 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader -- Loaded 2 bean definitions from class path resource [com/wpp/core/c1/s1_6/_3/DefaultInitAndDestroyDemo.xml]
09:59:04.088 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory -- Creating shared instance of singleton bean 'a'
A myInit
09:59:04.123 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory -- Creating shared instance of singleton bean 'b'
09:59:04.194 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext -- Closing org.springframework.context.support.ClassPathXmlApplicationContext@880ec60, started on Fri Apr 07 09:59:03 CST 2023
B myDestroy
09:59:04.197 [main] WARN org.springframework.beans.factory.support.DefaultListableBeanFactory -- Destruction of bean with name 'a' threw an exception
java.lang.NullPointerException: Cannot invoke "java.lang.reflect.Method.getParameterCount()" because "destroyMethod" is null
	at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:278)
	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:238)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:587)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:559)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:1189)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:520)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:1182)
	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1084)
	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1053)
	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:1003)
	at com.wpp.core.c1.s1_6._3.DefaultInitAndDestroyDemo.main(DefaultInitAndDestroyDemo.java:25)

Related Issues

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Apr 7, 2023
@sbrannen sbrannen changed the title NPE throws when configure default-destroy-method of xml NPE thrown when configuring default-destroy-method in XML config Apr 7, 2023
@sbrannen
Copy link
Member

sbrannen commented Apr 7, 2023

Hi @edfeff,

Thanks for raising the issue and providing the sample application.

It turns out that we already have a test in our own test suite which demonstrates the NullPointerException.

If we run org.springframework.beans.factory.xml.DefaultLifecycleMethodsTests.ignoreDefaultLifecycleMethods(), we see the following message logged at WARN level.

13:31:19.852 [main] WARN  o.s.b.f.s.DefaultListableBeanFactory - Destruction of bean with name 'foo' threw an exception
java.lang.NullPointerException: Cannot invoke "java.lang.reflect.Method.getParameterCount()" because "destroyMethod" is null
	at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:290) ~[main/:?]
	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:239) ~[main/:?]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:587) ~[main/:?]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:559) ~[main/:?]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:1189) ~[main/:?]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:520) ~[main/:?]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:1182) ~[main/:?]
	at org.springframework.beans.factory.xml.DefaultLifecycleMethodsTests.ignoreDefaultLifecycleMethods(DefaultLifecycleMethodsTests.java:70) ~[test/:?]

@sbrannen sbrannen self-assigned this Apr 7, 2023
@sbrannen sbrannen added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Apr 7, 2023
@sbrannen sbrannen added this to the 6.0.8 milestone Apr 7, 2023
@sbrannen sbrannen changed the title NPE thrown when configuring default-destroy-method in XML config NPE thrown and logged for nonexistent default-destroy-method in XML config Apr 7, 2023
@sbrannen sbrannen changed the title NPE thrown and logged for nonexistent default-destroy-method in XML config NPE thrown for nonexistent default-destroy-method in XML config Apr 7, 2023
@sbrannen sbrannen added type: regression A bug that is also a regression and removed type: enhancement A general enhancement labels Apr 7, 2023
@sbrannen
Copy link
Member

sbrannen commented Apr 7, 2023

This appears to have been a regression introduced in 6.0.x and has been fixed for inclusion in 6.0.8.

@sbrannen
Copy link
Member

sbrannen commented Apr 7, 2023

Reopening to investigate a potentially more suitable fix for the regression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

3 participants