Author: hlship
Date: Wed Sep 10 17:37:27 2008
New Revision: 694078

URL: http://svn.apache.org/viewvc?rev=694078&view=rev
Log:
TAPESTRY-2517:  failed service injection into a component field is visible in 
the browser as a spurious error about field _$resources

Added:
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FailedInjectDemo.java
Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java?rev=694078&r1=694077&r2=694078&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
 Wed Sep 10 17:37:27 2008
@@ -64,6 +64,8 @@
      */
     private final Map<String, Instantiator> classNameToInstantiator = 
CollectionFactory.newMap();
 
+    private final Map<String, RuntimeException> classToPriorTransformException 
= CollectionFactory.newMap();
+
     private CtClassSource classSource;
 
     private class PackageAwareLoader extends Loader
@@ -157,11 +159,11 @@
         }
 
         classFactory = new ClassFactoryImpl(loader, classPool, classSource, 
logger);
-    }
 
-    // This is called from well within a synchronized block.    The component 
layer class loader,
-    // and the context class loader, should each be locked.
+        classToPriorTransformException.clear();
+    }
 
+    // This is called from well within a synchronized block.
     public void onLoad(ClassPool pool, String classname) throws 
NotFoundException, CannotCompileException
     {
         logger.debug("BEGIN onLoad " + classname);
@@ -170,40 +172,51 @@
 
         String diag = "FAIL";
 
-        // If we are loading a class, it is because it is in a controlled 
package. There may be
-        // errors in the class that keep it from loading. By adding it to the 
change tracker
-        // early, we ensure that when the class is fixed, the change is picked 
up. Originally,
-        // this code was at the end of the method, and classes that contained 
errors would not be
-        // reloaded even after the code was fixed.
+        // TAPESTRY-2517: Attempting to re-transform a class that was 
partially transformed (but
+        // then failed) gives confusing exceptions if the user refreshes the 
failed page.
+        // Just give the same exception back.
 
-        addClassFileToChangeTracker(classname);
+        RuntimeException failure = 
classToPriorTransformException.get(classname);
 
-        try
+        if (failure == null)
         {
-            CtClass ctClass = pool.get(classname);
+            // If we are loading a class, it is because it is in a controlled 
package. There may be
+            // errors in the class that keep it from loading. By adding it to 
the change tracker
+            // early, we ensure that when the class is fixed, the change is 
picked up. Originally,
+            // this code was at the end of the method, and classes that 
contained errors would not be
+            // reloaded even after the code was fixed.
 
-            // Force the creation of the super-class before the target class.
+            addClassFileToChangeTracker(classname);
 
-            forceSuperclassTransform(ctClass);
+            try
+            {
+                CtClass ctClass = pool.get(classname);
 
-            // Do the transformations here
+                // Force the creation of the super-class before the target 
class.
 
-            transformer.transformComponentClass(ctClass, loader);
+                forceSuperclassTransform(ctClass);
 
-            writeClassToFileSystemForHardCoreDebuggingPurposesOnly(ctClass);
+                // Do the transformations here
 
-            diag = "END";
-        }
-        catch (RuntimeException classLoaderException)
-        {
-            
internalRequestGlobals.storeClassLoaderException(classLoaderException);
+                transformer.transformComponentClass(ctClass, loader);
 
-            throw classLoaderException;
-        }
-        finally
-        {
-            logger.debug(String.format("%5s onLoad %s", diag, classname));
+                
writeClassToFileSystemForHardCoreDebuggingPurposesOnly(ctClass);
+
+                diag = "END";
+            }
+            catch (RuntimeException classLoaderException)
+            {
+                
internalRequestGlobals.storeClassLoaderException(classLoaderException);
+
+                failure = classLoaderException;
+
+                classToPriorTransformException.put(classname, failure);
+            }
         }
+
+        logger.debug(String.format("%5s onLoad %s", diag, classname));
+
+        if (failure != null) throw failure;
     }
 
     private void 
writeClassToFileSystemForHardCoreDebuggingPurposesOnly(CtClass ctClass)

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java?rev=694078&r1=694077&r2=694078&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
 Wed Sep 10 17:37:27 2008
@@ -216,8 +216,7 @@
     public InternalClassTransformation createChildTransformation(CtClass 
childClass, MutableComponentModel childModel)
     {
         return new InternalClassTransformationImpl(childClass, this, 
classFactory, classSource, componentClassCache,
-                                                   childModel
-        );
+                                                   childModel);
     }
 
     private void freeze()

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml?rev=694078&r1=694077&r2=694078&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml Wed Sep 10 
17:37:27 2008
@@ -70,6 +70,10 @@
             <a href="fieldannotationconflict">Field Annotation Conflict</a>
             -- demo failure behavior when a field contains conflicting 
annotations
         </li>
+        <li>
+            <a href="failedinjectdemo">Failed Field Injection Demo</a>
+            -- demo failure when attempting to inject into a field
+        </li>
 
     </ul>
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java?rev=694078&r1=694077&r2=694078&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
 Wed Sep 10 17:37:27 2008
@@ -2237,4 +2237,23 @@
         assertTextSeries("//[EMAIL PROTECTED]'informals']/dt[%d]", 1, 
"barney", "fred", "pageName");
         assertTextSeries("//[EMAIL PROTECTED]'informals']/dd[%d]", 1, 
"rubble", "flintstone", "InformalParametersDemo");
     }
+
+    /**
+     * TAPESTRY-2517
+     */
+    public void cached_exception_for_loading_failed_page()
+    {
+        start("Failed Field Injection Demo");
+
+        assertTextPresent(
+                "Error obtaining injected value for field 
org.apache.tapestry5.integration.app1.pages.FailedInjectDemo.buffer: No service 
implements the interface java.lang.StringBuffer.");
+
+        refresh();
+        waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+
+        // Before this bug was fixed, this message would not appear; instead 
on complaining about _$resources would appear which was very confusing.
+
+        assertTextPresent(
+                "Error obtaining injected value for field 
org.apache.tapestry5.integration.app1.pages.FailedInjectDemo.buffer: No service 
implements the interface java.lang.StringBuffer.");
+    }
 }

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FailedInjectDemo.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FailedInjectDemo.java?rev=694078&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FailedInjectDemo.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FailedInjectDemo.java
 Wed Sep 10 17:37:27 2008
@@ -0,0 +1,23 @@
+//  Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.ioc.annotations.Inject;
+
+public class FailedInjectDemo
+{
+    @Inject
+    private StringBuffer buffer;
+}


Reply via email to