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;
+}