You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/05/01 03:23:10 UTC

svn commit: r652416 - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry/internal/services/ tapestry-core/src/main/java/org/apache/tapestry/services/ tapestry-ioc/src/site/apt/

Author: hlship
Date: Wed Apr 30 18:23:10 2008
New Revision: 652416

URL: http://svn.apache.org/viewvc?rev=652416&view=rev
Log:
TAPESTRY-2399: When an class loader exeption occurs while loading a base class, a new exception (int the subclass) overwrites the more useful exception from the base class

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestErrorFilter.java
Removed:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocationBuilder.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobals.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobalsImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobals.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobals.java?rev=652416&r1=652415&r2=652416&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobals.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobals.java Wed Apr 30 18:23:10 2008
@@ -19,6 +19,10 @@
  */
 public interface InternalRequestGlobals
 {
+    /**
+     * Stores the throwable for later; only the first such exception is kept (later exceptions are ignored, see
+     * TAPESTRY-2399).
+     */
     void storeClassLoaderException(Throwable classLoaderException);
 
     Throwable getClassLoaderException();

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobalsImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobalsImpl.java?rev=652416&r1=652415&r2=652416&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobalsImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobalsImpl.java Wed Apr 30 18:23:10 2008
@@ -30,6 +30,7 @@
 
     public void storeClassLoaderException(Throwable classLoaderException)
     {
-        _classLoaderException = classLoaderException;
+        if (_classLoaderException == null)
+            _classLoaderException = classLoaderException;
     }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestErrorFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestErrorFilter.java?rev=652416&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestErrorFilter.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestErrorFilter.java Wed Apr 30 18:23:10 2008
@@ -0,0 +1,94 @@
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+
+/**
+ * Filter for the {@link org.apache.tapestry.services.RequestHandler} pipeline used to intercept and report exceptions.
+ */
+public class RequestErrorFilter implements RequestFilter
+{
+    private final InternalRequestGlobals _internalRequestGlobals;
+    private final RequestExceptionHandler _exceptionHandler;
+
+    public RequestErrorFilter(InternalRequestGlobals internalRequestGlobals, RequestExceptionHandler exceptionHandler)
+    {
+        _internalRequestGlobals = internalRequestGlobals;
+        _exceptionHandler = exceptionHandler;
+    }
+
+    public boolean service(Request request, Response response, RequestHandler handler) throws IOException
+    {
+        try
+        {
+            return handler.service(request, response);
+        }
+        catch (IOException ex)
+        {
+            // Pass it through.
+            throw ex;
+        }
+        catch (Throwable ex)
+        {
+            // Most of the time, we've got exception linked up the kazoo ... but when ClassLoaders
+            // get involved, things go screwy.  Exceptions when transforming classes can cause
+            // a NoClassDefFoundError with no cause; here we're trying to link the cause back in.
+            // TAPESTRY-2078
+
+            Throwable exceptionToReport = attachNewCause(ex, _internalRequestGlobals.getClassLoaderException());
+
+            _exceptionHandler.handleRequestException(exceptionToReport);
+
+            // We assume a reponse has been sent and there's no need to handle the request
+            // further.
+
+            return true;
+        }
+    }
+
+    private Throwable attachNewCause(Throwable exception, Throwable underlyingCause)
+    {
+        if (underlyingCause == null) return exception;
+
+        Throwable current = exception;
+
+        while (current != null)
+        {
+
+            if (current == underlyingCause) return exception;
+
+            Throwable cause = current.getCause();
+
+            // Often, exceptions report themselves as their own cause.
+
+            if (current == cause) break;
+
+            if (cause == null)
+            {
+
+                try
+                {
+                    current.initCause(underlyingCause);
+
+                    return exception;
+                }
+                catch (IllegalStateException ex)
+                {
+                    // TAPESTRY-2284: sometimes you just can't init the cause, and there's no way to
+                    // find out without trying.
+
+                }
+            }
+
+            // Otherwise, continue working down the chain until we find a place where we can attach
+
+            current = cause;
+        }
+
+        // Found no place to report the exeption, so report the underlying cause (and lose out
+        // on all the other context).
+
+        return underlyingCause;
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=652416&r1=652415&r2=652416&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java Wed Apr 30 18:23:10 2008
@@ -562,8 +562,6 @@
      */
     public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration, Context context,
 
-                                         final RequestExceptionHandler exceptionHandler,
-
                                          // @Inject not needed because its a long, not a String
                                          @Symbol(TapestryConstants.FILE_CHECK_INTERVAL_SYMBOL)
                                          @IntermediateType(TimeInterval.class)
@@ -573,61 +571,12 @@
                                          @IntermediateType(TimeInterval.class)
                                          long updateTimeout,
 
-                                         final InternalRequestGlobals requestGlobals,
+                                         LocalizationSetter localizationSetter,
 
-                                         LocalizationSetter localizationSetter)
+                                         ObjectLocator locator)
     {
         RequestFilter staticFilesFilter = new StaticFilesFilter(context);
 
-        RequestFilter errorFilter = new RequestFilter()
-        {
-            public boolean service(Request request, Response response, RequestHandler handler) throws IOException
-            {
-                try
-                {
-                    return handler.service(request, response);
-                }
-                catch (IOException ex)
-                {
-                    // Pass it through.
-                    throw ex;
-                }
-                catch (Throwable ex)
-                {
-                    // Most of the time, we've got exception linked up the kazoo ... but when ClassLoaders
-                    // get involved, things go screwy.  Exceptions when transforming classes can cause
-                    // a NoClassDefFoundError with no cause; here we're trying to link the cause back in.
-                    // TAPESTRY-2078
-
-                    if (ex.getCause() == null)
-                    {
-                        Throwable cause = requestGlobals.getClassLoaderException();
-
-                        if (cause != null)
-                        {
-
-                            try
-                            {
-                                ex.initCause(cause);
-                            }
-                            catch (IllegalStateException ise)
-                            {
-                                // TAPESTRY-2284: sometimes you just can't init the cause, and there's no way to
-                                // find out without trying.
-                            }
-                        }
-                    }
-
-                    exceptionHandler.handleRequestException(ex);
-
-                    // We assume a reponse has been sent and there's no need to handle the request
-                    // further.
-
-                    return true;
-                }
-            }
-        };
-
         RequestFilter storeIntoGlobals = new RequestFilter()
         {
             public boolean service(Request request, Response response, RequestHandler handler) throws IOException
@@ -643,7 +592,7 @@
 
         configuration.add("StaticFiles", staticFilesFilter);
 
-        configuration.add("ErrorFilter", errorFilter);
+        configuration.add("ErrorFilter", locator.autobuild(RequestErrorFilter.class));
 
         configuration.add("StoreIntoGlobals", storeIntoGlobals);
 
@@ -2057,4 +2006,5 @@
         configuration.add("default", new DefaultNullFieldStrategy());
         configuration.add("zero", new ZeroNullFieldStrategy());
     }
+
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt?rev=652416&r1=652415&r2=652416&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt Wed Apr 30 18:23:10 2008
@@ -237,7 +237,7 @@
   query or even replace the return value.
 
   The
-  {{{../apidocs/org/apache/tapestry/service/AspectDecorator.html}AspectDecorator}} service
+  {{{../apidocs/org/apache/tapestry/ioc/services/AspectDecorator.html}AspectDecorator}} service
   is how you put your MethodAdvise into action.
 
   By way of an example, we'll show the current implementation of the LoggingDecorator service: