RESOLVED - BATCH-1465: Unwrap exceptions in AbstractMethodInvokingDelegator

This commit is contained in:
robokaso
2009-12-28 22:45:04 +00:00
parent 9790174503
commit 6f5f372375
4 changed files with 88 additions and 15 deletions

View File

@@ -31,6 +31,11 @@ import org.springframework.util.MethodInvoker;
* injected object. Provides convenient API for dynamic method invocation
* shielding subclasses from low-level details and exception handling.
*
* {@link Exception}s thrown by a successfully invoked delegate method are
* re-thrown without wrapping. In case the delegate method throws a
* {@link Throwable} that doesn't subclass {@link Exception} it will be wrapped
* by {@link InvocationTargetThrowableWrapper}.
*
* @author Robert Kasanicky
*/
public abstract class AbstractMethodInvokingDelegator<T> implements InitializingBean {
@@ -48,7 +53,7 @@ public abstract class AbstractMethodInvokingDelegator<T> implements Initializing
* @throws DynamicMethodInvocationException if the {@link MethodInvoker}
* used throws exception
*/
protected T invokeDelegateMethod() {
protected T invokeDelegateMethod() throws Exception {
MethodInvoker invoker = createMethodInvoker(targetObject, targetMethod);
invoker.setArguments(arguments);
return doInvoke(invoker);
@@ -61,7 +66,7 @@ public abstract class AbstractMethodInvokingDelegator<T> implements Initializing
* @throws DynamicMethodInvocationException if the {@link MethodInvoker}
* used throws exception
*/
protected T invokeDelegateMethodWithArgument(Object object) {
protected T invokeDelegateMethodWithArgument(Object object) throws Exception {
MethodInvoker invoker = createMethodInvoker(targetObject, targetMethod);
invoker.setArguments(new Object[] { object });
return doInvoke(invoker);
@@ -74,7 +79,7 @@ public abstract class AbstractMethodInvokingDelegator<T> implements Initializing
* @throws DynamicMethodInvocationException if the {@link MethodInvoker}
* used throws exception
*/
protected T invokeDelegateMethodWithArguments(Object[] args) {
protected T invokeDelegateMethodWithArguments(Object[] args) throws Exception {
MethodInvoker invoker = createMethodInvoker(targetObject, targetMethod);
invoker.setArguments(args);
return doInvoke(invoker);
@@ -97,7 +102,7 @@ public abstract class AbstractMethodInvokingDelegator<T> implements Initializing
* @return return value of the invoked method
*/
@SuppressWarnings("unchecked")
private T doInvoke(MethodInvoker invoker) {
private T doInvoke(MethodInvoker invoker) throws Exception {
try {
invoker.prepare();
}
@@ -112,7 +117,12 @@ public abstract class AbstractMethodInvokingDelegator<T> implements Initializing
return (T) invoker.invoke();
}
catch (InvocationTargetException e) {
throw new DynamicMethodInvocationException(e);
if (e.getCause() instanceof Exception) {
throw (Exception) e.getCause();
}
else {
throw new InvocationTargetThrowableWrapper(e.getCause());
}
}
catch (IllegalAccessException e) {
throw new DynamicMethodInvocationException(e);
@@ -132,14 +142,14 @@ public abstract class AbstractMethodInvokingDelegator<T> implements Initializing
*/
private boolean targetClassDeclaresTargetMethod() {
MethodInvoker invoker = createMethodInvoker(targetObject, targetMethod);
Method[] memberMethods = invoker.getTargetClass().getMethods();
Method[] declaredMethods = invoker.getTargetClass().getDeclaredMethods();
List<Method> allMethods = new ArrayList<Method>();
List<Method> allMethods = new ArrayList<Method>();
allMethods.addAll(Arrays.asList(memberMethods));
allMethods.addAll(Arrays.asList(declaredMethods));
String targetMethodName = invoker.getTargetMethod();
for (Method method : allMethods) {
@@ -199,4 +209,18 @@ public abstract class AbstractMethodInvokingDelegator<T> implements Initializing
public void setArguments(Object[] arguments) {
this.arguments = arguments;
}
/**
* Used to wrap a {@link Throwable} (not an {@link Exception}) thrown by a
* reflectively-invoked delegate.
*
* @author Robert Kasanicky
*/
public static class InvocationTargetThrowableWrapper extends RuntimeException {
public InvocationTargetThrowableWrapper(Throwable cause) {
super(cause);
}
}
}

View File

@@ -19,20 +19,23 @@ package org.springframework.batch.item.adapter;
import org.springframework.util.MethodInvoker;
/**
* Indicates an error has been encountered
* while trying to dynamically call a method e.g. using {@link MethodInvoker}.
* Indicates an error has been encountered while trying to dynamically invoke a
* method e.g. using {@link MethodInvoker}.
*
* The exception should be caused by a failed invocation of a method, it
* shouldn't be used to wrap an exception thrown by successfully invoked method.
*
* @author Robert Kasanicky
*/
public class DynamicMethodInvocationException extends RuntimeException {
//generated value
// generated value
private static final long serialVersionUID = -6056786139731564040L;
public DynamicMethodInvocationException(Throwable cause){
public DynamicMethodInvocationException(Throwable cause) {
super(cause);
}
public DynamicMethodInvocationException(String message, Throwable cause) {
super(message, cause);
}