I got fed up with XALAN wrapping all sorts of exception in stupid RuntimeException, without declaring them as the init cause (see org.apache.xalan.transformer.TransformerImpl.run(TransformerImpl.java: 3418) for an example).

So, I wrote a little patch that might (if very lucky) reconstruct the original exception from the message of a wrapped one by Xalan.

This happens when (for example) you have cinclude after xalan, if cinclude fails, xalan will throw a RuntimeException without wrapping the original ResourceNotFoundException, but simply including it in its name.

What this patch does is that if the exception being processed is a RuntimeException (not a subclass of), and the cause is null, it will try to recreate an exception instance from the detail message, and if successful, will declare that as the cause (thus allowing the ExceptionSelector to process almost correctly).

    Pier

--- ExceptionSelector.java.orig    2004-05-24 09:12:09.000000000 +0100
+++ ExceptionSelector.java   2005-07-25 13:53:16.000000000 +0100
@@ -15,6 +15,7 @@
  */
 package org.apache.cocoon.selection;
 
+import java.lang.reflect.Constructor;
 import java.util.Map;
 
 import org.apache.avalon.framework.configuration.Configurable;
@@ -22,6 +23,7 @@
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.parameters.Parameters;
 import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.selection.AbstractSwitchSelector;
 import org.apache.cocoon.util.ClassUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
 
@@ -128,8 +130,26 @@
                 // return the cause name, if not null (recursively)
                 if (this.unroll[i]) {
                     Throwable cause = ExceptionUtils.getCause(thr);
+                    
+                    // XALAN throws rogue RuntimeException in its "run()" 
method (???)
+                    if ((cause == null) && (thr.getClass() == 
RuntimeException.class)) try {
+                        int pos = thr.getMessage().indexOf(": ");
+                        if (pos > 0) {
+                            String clnam = thr.getMessage().substring(0, pos);
+                            String messg = "(Rebuilt) " + 
thr.getMessage().substring(pos + 2);
+                            Class clazz = Class.forName(clnam);
+                            Constructor cstrc = clazz.getConstructor(new 
Class[] {String.class});
+                            cause = (Throwable) cstrc.newInstance(new String[] 
{messg});
+                            thr.initCause(cause);
+                        }
+                    } catch (Throwable throwable) {
+                        // Ignore anything that might occur above
+                    }
+
+                    // We should have a cause even if Xalan wrapped it!
                     if (cause != null) {
                         FindResult result = find(cause);
+                        System.err.println("RESULT FOR " + 
cause.getClass().getName() + ": " + result);
                         if (result != null) {
                             return result;
                         }

Reply via email to