Browse Source

revised destroy method lookup after deserialization (avoiding NPE in case of default-destroy-method; SPR-6211)

pull/23217/head
Juergen Hoeller 15 years ago
parent
commit
11d987009a
  1. 65
      org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java

65
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java

@ -74,6 +74,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -74,6 +74,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
private final AccessControlContext acc;
/**
* Create a new DisposableBeanAdapter for the given bean.
* @param bean the bean instance (never <code>null</code>)
@ -97,27 +98,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -97,27 +98,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
destroyMethod = (nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(bean.getClass(), destroyMethodName) :
BeanUtils.findMethodWithMinimalParameters(bean.getClass().getMethods(), destroyMethodName));
return null;
}
});
}
else {
this.destroyMethod = (this.nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(bean.getClass(), destroyMethodName) :
BeanUtils.findMethodWithMinimalParameters(bean.getClass().getMethods(), destroyMethodName));
}
}
catch (IllegalArgumentException ex) {
throw new BeanDefinitionValidationException("Couldn't find a unique destroy method on bean with name '" +
this.beanName + ": " + ex.getMessage());
}
this.destroyMethod = determineDestroyMethod();
if (this.destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Couldn't find a destroy method named '" +
@ -193,7 +174,6 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -193,7 +174,6 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
((DisposableBean) bean).destroy();
return null;
@ -219,13 +199,39 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -219,13 +199,39 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
this.destroyMethod = (this.nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass(), this.destroyMethodName) :
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass().getMethods(), this.destroyMethodName));
invokeCustomDestroyMethod(this.destroyMethod);
Method methodToCall = determineDestroyMethod();
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
private Method determineDestroyMethod() {
try {
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new PrivilegedAction<Method>() {
public Method run() {
return findDestroyMethod();
}
});
}
else {
return findDestroyMethod();
}
}
catch (IllegalArgumentException ex) {
throw new BeanDefinitionValidationException("Couldn't find a unique destroy method on bean with name '" +
this.beanName + ": " + ex.getMessage());
}
}
private Method findDestroyMethod() {
return (this.nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass(), this.destroyMethodName) :
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass().getMethods(), this.destroyMethodName));
}
/**
* Invoke the specified custom destroy method on the given bean.
* <p>This implementation invokes a no-arg method if found, else checking
@ -250,7 +256,6 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -250,7 +256,6 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
return null;
}
});
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
@ -258,7 +263,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -258,7 +263,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
return null;
}
}, acc);
} catch (PrivilegedActionException pax) {
}
catch (PrivilegedActionException pax) {
throw (InvocationTargetException) pax.getException();
}
}
@ -266,7 +272,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -266,7 +272,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
ReflectionUtils.makeAccessible(destroyMethod);
destroyMethod.invoke(bean, args);
}
} catch (InvocationTargetException ex) {
}
catch (InvocationTargetException ex) {
String msg = "Invocation of destroy method '" + this.destroyMethodName +
"' failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {

Loading…
Cancel
Save