diff --git a/src/main/java/org/apache/commons/pool2/proxy/BaseProxyHandler.java b/src/main/java/org/apache/commons/pool2/proxy/BaseProxyHandler.java index 26c571a49..7bb35451e 100644 --- a/src/main/java/org/apache/commons/pool2/proxy/BaseProxyHandler.java +++ b/src/main/java/org/apache/commons/pool2/proxy/BaseProxyHandler.java @@ -16,6 +16,7 @@ */ package org.apache.commons.pool2.proxy; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.commons.pool2.UsageTracking; @@ -32,19 +33,22 @@ class BaseProxyHandler { private volatile T pooledObject; private final UsageTracking usageTracking; + private final boolean unwrapInvocationTargetException; /** * Create a new wrapper for the given pooled object. * - * @param pooledObject The object to wrap - * @param usageTracking The instance, if any (usually the object pool) to - * be provided with usage tracking information for this - * wrapped object + * @param pooledObject The object to wrap + * @param usageTracking The instance, if any (usually the object pool) to + * be provided with usage tracking information for this + * wrapped object + * @param unwrapInvocationTargetException True to make the proxy throw {@link InvocationTargetException#getTargetException()} instead of {@link InvocationTargetException} */ - BaseProxyHandler(final T pooledObject, final UsageTracking usageTracking) { + BaseProxyHandler(final T pooledObject, final UsageTracking usageTracking, boolean unwrapInvocationTargetException) { this.pooledObject = pooledObject; this.usageTracking = usageTracking; + this.unwrapInvocationTargetException = unwrapInvocationTargetException; } @@ -76,7 +80,14 @@ Object doInvoke(final Method method, final Object[] args) throws Throwable { if (usageTracking != null) { usageTracking.use(object); } - return method.invoke(object, args); + try { + return method.invoke(object, args); + } catch (InvocationTargetException e) { + if (unwrapInvocationTargetException) { + throw e.getTargetException(); + } + throw e; + } } diff --git a/src/main/java/org/apache/commons/pool2/proxy/CglibProxyHandler.java b/src/main/java/org/apache/commons/pool2/proxy/CglibProxyHandler.java index 1ff3891c1..4d0def202 100644 --- a/src/main/java/org/apache/commons/pool2/proxy/CglibProxyHandler.java +++ b/src/main/java/org/apache/commons/pool2/proxy/CglibProxyHandler.java @@ -16,6 +16,7 @@ */ package org.apache.commons.pool2.proxy; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.commons.pool2.UsageTracking; @@ -37,13 +38,14 @@ class CglibProxyHandler extends BaseProxyHandler /** * Create a CGLib proxy instance. * - * @param pooledObject The object to wrap - * @param usageTracking The instance, if any (usually the object pool) to - * be provided with usage tracking information for this - * wrapped object + * @param pooledObject The object to wrap + * @param usageTracking The instance, if any (usually the object pool) to + * be provided with usage tracking information for this + * wrapped object + * @param unwrapInvocationTargetException True to make the proxy throw {@link InvocationTargetException#getTargetException()} instead of {@link InvocationTargetException} */ - CglibProxyHandler(final T pooledObject, final UsageTracking usageTracking) { - super(pooledObject, usageTracking); + CglibProxyHandler(final T pooledObject, final UsageTracking usageTracking, boolean unwrapInvocationTargetException) { + super(pooledObject, usageTracking, unwrapInvocationTargetException); } @Override diff --git a/src/main/java/org/apache/commons/pool2/proxy/CglibProxySource.java b/src/main/java/org/apache/commons/pool2/proxy/CglibProxySource.java index 15592be31..2b08355f2 100644 --- a/src/main/java/org/apache/commons/pool2/proxy/CglibProxySource.java +++ b/src/main/java/org/apache/commons/pool2/proxy/CglibProxySource.java @@ -16,6 +16,7 @@ */ package org.apache.commons.pool2.proxy; +import java.lang.reflect.InvocationTargetException; import org.apache.commons.pool2.UsageTracking; import net.sf.cglib.proxy.Enhancer; @@ -31,14 +32,26 @@ public class CglibProxySource implements ProxySource { private final Class superclass; + private final boolean unwrapInvocationTargetException; /** * Create a new proxy source for the given class. * + * @param superclass The class to proxy + * @param unwrapInvocationTargetException True to make the proxy throw {@link InvocationTargetException#getTargetException()} instead of {@link InvocationTargetException} + */ + public CglibProxySource(final Class superclass, boolean unwrapInvocationTargetException) { + this.superclass = superclass; + this.unwrapInvocationTargetException = unwrapInvocationTargetException; + } + + /** + * Constructs a new proxy source for the given class. + * * @param superclass The class to proxy */ public CglibProxySource(final Class superclass) { - this.superclass = superclass; + this(superclass, false); } @Override @@ -47,7 +60,7 @@ public T createProxy(final T pooledObject, final UsageTracking usageTracking) enhancer.setSuperclass(superclass); final CglibProxyHandler proxyInterceptor = - new CglibProxyHandler<>(pooledObject, usageTracking); + new CglibProxyHandler<>(pooledObject, usageTracking, unwrapInvocationTargetException); enhancer.setCallback(proxyInterceptor); @SuppressWarnings("unchecked") diff --git a/src/main/java/org/apache/commons/pool2/proxy/JdkProxyHandler.java b/src/main/java/org/apache/commons/pool2/proxy/JdkProxyHandler.java index b1f863658..7aadc02de 100644 --- a/src/main/java/org/apache/commons/pool2/proxy/JdkProxyHandler.java +++ b/src/main/java/org/apache/commons/pool2/proxy/JdkProxyHandler.java @@ -17,6 +17,7 @@ package org.apache.commons.pool2.proxy; import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.commons.pool2.UsageTracking; @@ -34,13 +35,14 @@ class JdkProxyHandler extends BaseProxyHandler /** * Create a Java reflection proxy instance. * - * @param pooledObject The object to wrap - * @param usageTracking The instance, if any (usually the object pool) to - * be provided with usage tracking information for this - * wrapped object + * @param pooledObject The object to wrap + * @param usageTracking The instance, if any (usually the object pool) to + * be provided with usage tracking information for this + * wrapped object + * @param unwrapInvocationTargetException True to make the proxy throw {@link InvocationTargetException#getTargetException()} instead of {@link InvocationTargetException} */ - JdkProxyHandler(final T pooledObject, final UsageTracking usageTracking) { - super(pooledObject, usageTracking); + JdkProxyHandler(final T pooledObject, final UsageTracking usageTracking, boolean unwrapInvocationTargetException) { + super(pooledObject, usageTracking, unwrapInvocationTargetException); } diff --git a/src/main/java/org/apache/commons/pool2/proxy/JdkProxySource.java b/src/main/java/org/apache/commons/pool2/proxy/JdkProxySource.java index b2036c99c..60080198a 100644 --- a/src/main/java/org/apache/commons/pool2/proxy/JdkProxySource.java +++ b/src/main/java/org/apache/commons/pool2/proxy/JdkProxySource.java @@ -16,6 +16,7 @@ */ package org.apache.commons.pool2.proxy; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Proxy; import java.util.Arrays; @@ -32,6 +33,7 @@ public class JdkProxySource implements ProxySource { private final ClassLoader classLoader; private final Class[] interfaces; + private final boolean unwrapInvocationTargetException; /** @@ -39,12 +41,24 @@ public class JdkProxySource implements ProxySource { * * @param classLoader The class loader with which to create the proxy * @param interfaces The interfaces to proxy + * @param unwrapInvocationTargetException True to make the proxy throw {@link InvocationTargetException#getTargetException()} instead of {@link InvocationTargetException} */ - public JdkProxySource(final ClassLoader classLoader, final Class[] interfaces) { + public JdkProxySource(final ClassLoader classLoader, final Class[] interfaces, boolean unwrapInvocationTargetException) { this.classLoader = classLoader; // Defensive copy this.interfaces = new Class[interfaces.length]; System.arraycopy(interfaces, 0, this.interfaces, 0, interfaces.length); + this.unwrapInvocationTargetException = unwrapInvocationTargetException; + } + + /** + * Constructs a new proxy source for the given interfaces. + * + * @param classLoader The class loader with which to create the proxy + * @param interfaces The interfaces to proxy + */ + public JdkProxySource(final ClassLoader classLoader, final Class[] interfaces) { + this(classLoader, interfaces, false); } @@ -53,11 +67,10 @@ public T createProxy(final T pooledObject, final UsageTracking usageTracking) @SuppressWarnings("unchecked") final T proxy = (T) Proxy.newProxyInstance(classLoader, interfaces, - new JdkProxyHandler<>(pooledObject, usageTracking)); + new JdkProxyHandler<>(pooledObject, usageTracking, unwrapInvocationTargetException)); return proxy; } - @Override public T resolveProxy(final T proxy) { @SuppressWarnings("unchecked")