You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ni...@apache.org on 2007/05/22 01:36:17 UTC
svn commit: r540362 - in /jakarta/commons/proper/beanutils/trunk/src:
java/org/apache/commons/beanutils/ test/org/apache/commons/beanutils/
Author: niallp
Date: Mon May 21 16:36:17 2007
New Revision: 540362
URL: http://svn.apache.org/viewvc?view=rev&rev=540362
Log:
Fix for BEANUTILS-266 Log or throw exception in PropertyUtilsBean - thanks to Brian Ewins and Commons HttpClient. Added mechanism to initialize the "cause" on an Exception using reflection (copied from Commons HttpClient).
Modified:
jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java
jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtilsBean.java
jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/BeanUtilsTestCase.java
Modified: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java?view=diff&rev=540362&r1=540361&r2=540362
==============================================================================
--- jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java (original)
+++ jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtils.java Mon May 21 16:36:17 2007
@@ -455,4 +455,15 @@
BeanUtilsBean.getInstance().setProperty(bean, name, value);
}
+
+ /**
+ * If we're running on JDK 1.4 or later, initialize the cause for the given throwable.
+ *
+ * @param throwable The throwable.
+ * @param cause The cause of the throwable.
+ * @return true if the cause was initialized, otherwise false.
+ */
+ public static boolean initCause(Throwable throwable, Throwable cause) {
+ return BeanUtilsBean.getInstance().initCause(throwable, cause);
+ }
}
Modified: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtilsBean.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtilsBean.java?view=diff&rev=540362&r1=540361&r2=540362
==============================================================================
--- jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtilsBean.java (original)
+++ jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/BeanUtilsBean.java Mon May 21 16:36:17 2007
@@ -23,6 +23,7 @@
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -103,6 +104,9 @@
/** Used to access properties*/
private PropertyUtilsBean propertyUtilsBean;
+ /** A reference to Throwable's initCause method, or null if it's not there in this JVM */
+ private static final Method INIT_CAUSE_METHOD = getInitCauseMethod();
+
// --------------------------------------------------------- Constuctors
/**
@@ -1028,5 +1032,51 @@
*/
public PropertyUtilsBean getPropertyUtils() {
return propertyUtilsBean;
+ }
+
+ /**
+ * If we're running on JDK 1.4 or later, initialize the cause for the given throwable.
+ *
+ * @param throwable The throwable.
+ * @param cause The cause of the throwable.
+ * @return true if the cause was initialized, otherwise false.
+ */
+ public boolean initCause(Throwable throwable, Throwable cause) {
+ if (INIT_CAUSE_METHOD != null && cause != null) {
+ try {
+ INIT_CAUSE_METHOD.invoke(throwable, new Object[] { cause });
+ return true;
+ } catch (Throwable e) {
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a <code>Method<code> allowing access to
+ * {@link Throwable#initCause(Throwable)} method of {@link Throwable},
+ * or <code>null</code> if the method
+ * does not exist.
+ *
+ * @return A <code>Method<code> for <code>Throwable.initCause</code>, or
+ * <code>null</code> if unavailable.
+ */
+ private static Method getInitCauseMethod() {
+ try {
+ Class[] paramsClasses = new Class[] { Throwable.class };
+ return Throwable.class.getMethod("initCause", paramsClasses);
+ } catch (NoSuchMethodException e) {
+ Log log = LogFactory.getLog(BeanUtils.class);
+ if (log.isWarnEnabled()) {
+ log.warn("Throwable does not have initCause() method in JDK 1.3");
+ }
+ return null;
+ } catch (Throwable e) {
+ Log log = LogFactory.getLog(BeanUtils.class);
+ if (log.isWarnEnabled()) {
+ log.warn("Error getting the Throwable initCause() method", e);
+ }
+ return null;
+ }
}
}
Modified: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java?view=diff&rev=540362&r1=540361&r2=540362
==============================================================================
--- jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java (original)
+++ jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java Mon May 21 16:36:17 2007
@@ -2001,7 +2001,7 @@
return method.invoke(bean, values);
- } catch (IllegalArgumentException e) {
+ } catch (IllegalArgumentException cause) {
if(bean == null) {
throw new IllegalArgumentException("No bean specified " +
"- this should have been checked before reaching this method");
@@ -2025,16 +2025,19 @@
expectedString += parTypes[i].getName();
}
}
- log.error("Method invocation failed", e);
- throw new IllegalArgumentException(
+ IllegalArgumentException e = new IllegalArgumentException(
"Cannot invoke " + method.getDeclaringClass().getName() + "."
+ method.getName() + " on bean class '" + bean.getClass() +
- "' - " + e.getMessage()
+ "' - " + cause.getMessage()
// as per https://issues.apache.org/jira/browse/BEANUTILS-224
+ " - had objects of type \"" + valueString
+ "\" but expected signature \""
+ expectedString + "\""
);
+ if (!BeanUtils.initCause(e, cause)) {
+ log.error("Method invocation failed", cause);
+ }
+ throw e;
}
}
Modified: jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/BeanUtilsTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/BeanUtilsTestCase.java?view=diff&rev=540362&r1=540361&r2=540362
==============================================================================
--- jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/BeanUtilsTestCase.java (original)
+++ jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/BeanUtilsTestCase.java Mon May 21 16:36:17 2007
@@ -22,6 +22,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.StringTokenizer;
import junit.framework.Test;
import junit.framework.TestCase;
@@ -1367,4 +1368,72 @@
"some.dotty.value",
bean.getMapproperty("this.that.the-other"));
}
+
+ /**
+ * Test for {@link BeanUtilsBean#initCause(Throwable, Throwable)} method.
+ */
+ public void testInitCause() {
+ if (isPre14JVM()) {
+ return;
+ }
+ String parentMsg = "PARENT-THROWABLE";
+ String causeMsg = "THROWABLE-CAUSE";
+ try {
+ initCauseAndThrowException(parentMsg, causeMsg);
+ } catch (Throwable thrownParent) {
+ assertEquals("Parent", parentMsg, thrownParent.getMessage());
+ try {
+ assertEquals("Parent", parentMsg, thrownParent.getMessage());
+ Throwable thrownCause = getCause(thrownParent);
+ assertNotNull("Cause Null", thrownCause);
+ assertEquals("Cause", causeMsg, thrownCause.getMessage());
+ } catch (Throwable testError) {
+ fail("If you're running JDK 1.3 then don't worry this should fail," +
+ " if not then needs checking out: " + testError);
+ }
+ }
+ }
+
+ /**
+ * Use reflection to get the cause
+ */
+ private Throwable getCause(Throwable t) throws Throwable {
+ return (Throwable)PropertyUtils.getProperty(t, "cause");
+ }
+
+ /**
+ * Catch a cause, initialize using BeanUtils.initCause() and throw new exception
+ */
+ private void initCauseAndThrowException(String parent, String cause) throws Throwable {
+ try {
+ throwException(cause);
+ } catch (Throwable e) {
+ Throwable t = new Exception(parent);
+ BeanUtils.initCause(t, e);
+ throw t;
+ }
+ }
+
+ /**
+ * Throw an exception with the specified message.
+ */
+ private void throwException(String msg) throws Throwable {
+ throw new Exception(msg);
+ }
+
+ /**
+ * Test for JDK 1.4
+ */
+ private boolean isPre14JVM() {
+ String version = System.getProperty("java.specification.version");
+ StringTokenizer tokenizer = new StringTokenizer(version,".");
+ if (tokenizer.nextToken().equals("1")) {
+ String minorVersion = tokenizer.nextToken();
+ if (minorVersion.equals("0")) return true;
+ if (minorVersion.equals("1")) return true;
+ if (minorVersion.equals("2")) return true;
+ if (minorVersion.equals("3")) return true;
+ }
+ return false;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org