We’ve just started using HiveMind and one error that I’ve seen rather frequently is the “Unable to process attribute ____ (of element entry/option): ___ does not contain a property named ‘___’.”  Its always operator error but it can be rather frustrating to go digging into the Java source only to find that someone forgot to update a jar file.  As a result, we’ve added a debug message that is logged just before throwing the error.  This message displays the property introspection on the offending object making it very easy to determine the appropriate course of action.

 

A sample message looks like:

[org.apache.hivemind.util.ClassAdaptor] Class MyMapEntry contains the properties named 'class(RO), name(RW), value(RW)'.

 

Kevin

 

diff -ur framework.backup/src/java/org/apache/hivemind/util/ClassAdaptor.java 
framework/src/java/org/apache/hivemind/util/ClassAdaptor.java
--- framework.backup/src/java/org/apache/hivemind/util/ClassAdaptor.java        
Sat Sep  3 11:21:46 2005
+++ framework/src/java/org/apache/hivemind/util/ClassAdaptor.java       Wed Nov 
 9 19:23:20 2005
@@ -16,12 +16,15 @@
 
 import java.beans.PropertyDescriptor;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.hivemind.ApplicationRuntimeException;
 
 /**
@@ -32,6 +35,8 @@
  */
 class ClassAdaptor
 {
+    private static final Log LOG = LogFactory.getLog(ClassAdaptor.class);
+
     private final Map _propertyAdaptorMap = new HashMap();
 
     ClassAdaptor(PropertyDescriptor[] properties)
@@ -133,8 +138,13 @@
         PropertyAdaptor result = (PropertyAdaptor) 
_propertyAdaptorMap.get(propertyName);
 
         if (result == null)
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug(UtilMessages.listAllProperties(target, this));
+
             throw new ApplicationRuntimeException(
                     UtilMessages.noSuchProperty(target, propertyName), target, 
null, null);
+        }
 
         return result;
     }
@@ -177,6 +187,14 @@
         }
 
         return result;
+    }
+
+    /**
+     * Return an immutable map of property names to PropertyAdaptor objects
+     */
+    public Map getPropertyAdaptorMap()
+    {
+        return Collections.unmodifiableMap(_propertyAdaptorMap);
     }
 
     /**
diff -ur framework.backup/src/java/org/apache/hivemind/util/UtilMessages.java 
framework/src/java/org/apache/hivemind/util/UtilMessages.java
--- framework.backup/src/java/org/apache/hivemind/util/UtilMessages.java        
Sat Sep  3 11:21:46 2005
+++ framework/src/java/org/apache/hivemind/util/UtilMessages.java       Thu Nov 
 3 19:51:20 2005
@@ -17,6 +17,11 @@
 import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
 import org.apache.hivemind.impl.MessageFormatter;
 
 /**
@@ -27,6 +32,40 @@
 class UtilMessages
 {
     protected static MessageFormatter _formatter = new 
MessageFormatter(UtilMessages.class);
+
+    static String listAllProperties(Object target, ClassAdaptor adaptor) {
+        final Map properties = adaptor.getPropertyAdaptorMap();
+        final SortedSet sortedPropertyNames = new TreeSet(properties.keySet());
+        final String RO = 
_formatter.getMessage("read-only-property-indicator");
+        final String WO = 
_formatter.getMessage("write-only-property-indicator");
+        final String RW = 
_formatter.getMessage("read-write-property-indicator");
+
+        StringBuffer buf = new StringBuffer(64);
+        boolean multi = false;
+
+        for (Iterator i = sortedPropertyNames.iterator(); i.hasNext();) {
+            String propertyName = (String) i.next();
+
+            PropertyAdaptor pa = (PropertyAdaptor) 
properties.get(propertyName);
+
+            String indicator = "";
+
+            if (pa.isReadable())
+                indicator = pa.isWritable() ? RW : RO;
+            else
+                indicator = WO;
+
+            if (multi) {
+                buf.append(", ");
+            }
+
+            buf.append(propertyName).append("(").append(indicator).append(")");
+
+            multi = true;
+        }
+
+        return _formatter.format("list-all-properties", 
target.getClass().getName(), buf.toString());
+    }
 
     static String noSuchProperty(Object target, String propertyName)
     {
diff -ur 
framework.backup/src/java/org/apache/hivemind/util/UtilStrings.properties 
framework/src/java/org/apache/hivemind/util/UtilStrings.properties
--- framework.backup/src/java/org/apache/hivemind/util/UtilStrings.properties   
Sat Sep  3 11:21:46 2005
+++ framework/src/java/org/apache/hivemind/util/UtilStrings.properties  Thu Nov 
 3 19:57:01 2005
@@ -13,6 +13,10 @@
 # limitations under the License.
 
 no-such-property=Class {0} does not contain a property named ''{1}''.
+list-all-properties=Class {0} contains the properties named {1}.
+read-only-property-indicator=RO
+write-only-property-indicator=WO
+read-write-property-indicator=RW
 no-matching-constructor=Unable to find a constructor for class {0}.
 invoke-failed=Failure invoking constructor for class {0}: {1}
 no-writer=Property {0} of object {1} is read-only.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to