Author: hlship
Date: Sun Nov 26 10:25:21 2006
New Revision: 479391

URL: http://svn.apache.org/viewvc?view=rev&rev=479391
Log:
Add a base package, under the root package, for base classes.
Ensure that even component classes that contain errors will be reloaded once 
changed.

Added:
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java
      - copied, changed from r479384, 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java
Removed:
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java
Modified:
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java
    
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt
    
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentClassResolverImplTest.java

Copied: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java
 (from r479384, 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java)
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java?view=diff&rev=479391&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java&r1=479384&p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java&r2=479391
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java
 Sun Nov 26 10:25:21 2006
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.corelib.components;
+package org.apache.tapestry.corelib.base;
 
 import java.io.Serializable;
 

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java?view=diff&rev=479391&r1=479390&r2=479391
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java
 Sun Nov 26 10:25:21 2006
@@ -18,6 +18,7 @@
 import org.apache.tapestry.annotations.AfterRender;
 import org.apache.tapestry.annotations.BeginRender;
 import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.corelib.base.AbstractField;
 import org.apache.tapestry.services.WebRequest;
 
 /** A Checkbox coponent is simply a <input type="checkbox">. */

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextArea.java?view=diff&rev=479391&r1=479390&r2=479391
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
 Sun Nov 26 10:25:21 2006
@@ -19,6 +19,7 @@
 import org.apache.tapestry.annotations.BeforeRenderBody;
 import org.apache.tapestry.annotations.BeginRender;
 import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.corelib.base.AbstractField;
 import org.apache.tapestry.services.WebRequest;
 
 /**

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java?view=diff&rev=479391&r1=479390&r2=479391
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java
 Sun Nov 26 10:25:21 2006
@@ -18,6 +18,7 @@
 import org.apache.tapestry.annotations.AfterRender;
 import org.apache.tapestry.annotations.BeginRender;
 import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.corelib.base.AbstractField;
 import org.apache.tapestry.services.WebRequest;
 
 /**

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java?view=diff&rev=479391&r1=479390&r2=479391
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
 Sun Nov 26 10:25:21 2006
@@ -88,6 +88,7 @@
         _componentInstantiatorSource.addPackage(rootPackage + ".pages");
         _componentInstantiatorSource.addPackage(rootPackage + ".components");
         _componentInstantiatorSource.addPackage(rootPackage + ".mixins");
+        _componentInstantiatorSource.addPackage(rootPackage + ".base");
     }
 
     /** When the class loader is invalidated, clear any cached page names or 
component types. */

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java?view=diff&rev=479391&r1=479390&r2=479391
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java
 Sun Nov 26 10:25:21 2006
@@ -12,258 +12,269 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.services;
-
+package org.apache.tapestry.internal.services;
+
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
-
-import java.net.URL;
-import java.util.Map;
-import java.util.Set;
-
-import javassist.CannotCompileException;
-import javassist.ClassPath;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.Loader;
-import javassist.LoaderClassPath;
-import javassist.NotFoundException;
-import javassist.Translator;
-
-import org.apache.commons.logging.Log;
-import org.apache.tapestry.events.UpdateListener;
-import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
-import org.apache.tapestry.internal.util.URLChangeTracker;
+
+import java.net.URL;
+import java.util.Map;
+import java.util.Set;
+
+import javassist.CannotCompileException;
+import javassist.ClassPath;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.Loader;
+import javassist.LoaderClassPath;
+import javassist.NotFoundException;
+import javassist.Translator;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.events.UpdateListener;
+import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
+import org.apache.tapestry.internal.util.URLChangeTracker;
 import org.apache.tapestry.ioc.internal.util.Defense;
-
-/**
- * A wrapper around a Javassist class loader that allows certain classes to be 
modified as they are
- * loaded.
- */
-public final class ComponentInstantiatorSourceImpl extends 
InvalidationEventHubImpl implements
-        Translator, ComponentInstantiatorSource, UpdateListener
-{
-    private final Set<String> _controlledPackageNames = newSet();
-
-    private final URLChangeTracker _changeTracker = new URLChangeTracker();
-
-    private final ClassLoader _parent;
-
-    private ClassPool _classPool;
-
-    private Loader _loader;
-
-    private final ComponentClassTransformer _transformer;
-
-    private final Log _log;
-
-    /** Map from class name to Instantiator. */
-    private final Map<String, Instantiator> _instantiatorMap = newMap();
-
-    private class PackageAwareLoader extends Loader
-    {
-        public PackageAwareLoader(ClassLoader parent, ClassPool classPool)
-        {
-            super(parent, classPool);
-        }
-
-        @Override
-        protected Class findClass(String className) throws 
ClassNotFoundException
-        {
-            if (inControlledPackage(className))
-                return super.findClass(className);
-
-            // Returning null forces delegation to the parent class loader.
-
-            return null;
-        }
-
-    }
-
-    public ComponentInstantiatorSourceImpl(ClassLoader parent,
-            ComponentClassTransformer transformer, Log log)
-    {
-        _parent = parent;
-        _transformer = transformer;
-        _log = log;
-
-        initializeService();
-    }
-
-    /** @return the class loader used when loading enhanced/modified classes */
-    public ClassLoader getClassLoader()
-    {
-        return _loader;
-    }
-
-    public synchronized void checkForUpdates()
-    {
-        if (!_changeTracker.containsChanges())
-            return;
-
-        _changeTracker.clear();
-        _instantiatorMap.clear();
-
-        // Release the existing class pool, loader and so forth.
-        // Create a new one.
-
-        initializeService();
-
-        // Tell everyone that the world has changed and they should discard
-        // their cache.
-
-        fireInvalidationEvent();
-    }
-
-    /**
-     * Invoked at object creation, or when there are updates to class files 
(i.e., invalidation), to
-     * create a new set of Javassist class pools and loaders.
-     */
-    private void initializeService()
-    {
-        _classPool = new ClassPool();
-
-        ClassPath path = new LoaderClassPath(_parent);
-
-        _classPool.appendClassPath(path);
-
-        _loader = new PackageAwareLoader(_parent, _classPool);
-
-        try
-        {
-            _loader.addTranslator(_classPool, this);
-        }
-        catch (Exception ex)
-        {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    // This is called from well within a synchronized block.
-    public void onLoad(ClassPool pool, String classname) throws 
NotFoundException,
-            CannotCompileException
-    {
-        _log.debug("BEGIN onLoad " + classname);
-
-        // This is our chance to make changes to the CtClass before it is 
loaded into memory.
-
-        String diag = "FAIL";
-
-        try
-        {
-            CtClass ctClass = pool.get(classname);
-
-            // Force the creation of the super-class before the target class.
-
-            forceSuperclassTransform(ctClass);
-
-            // Do the transformations here
-
-            _transformer.transformComponentClass(ctClass, _loader);
-
-            diag = "END";
-        }
-        catch (ClassNotFoundException ex)
-        {
-            throw new CannotCompileException(ex);
-        }
-        finally
-        {
-            _log.debug(String.format("%5s onLoad %s", diag, classname));
-        }
-
-        String path = classname.replace('.', '/') + ".class";
-
-        URL url = _loader.getResource(path);
-
-        _changeTracker.add(url);
-    }
-
-    private void forceSuperclassTransform(CtClass ctClass) throws 
NotFoundException,
-            ClassNotFoundException
-    {
-        CtClass superClass = ctClass.getSuperclass();
-
-        findClass(superClass.getName());
-    }
-
-    /** Does nothing. */
-    public void start(ClassPool pool) throws NotFoundException, 
CannotCompileException
-    {
-    }
-
-    public synchronized Instantiator findInstantiator(String classname)
-    {
-        Instantiator result = _instantiatorMap.get(classname);
-
-        if (result == null)
-        {
-            Class instanceClass = findClass(classname);
-
-            result = _transformer.createInstantiator(instanceClass);
-
-            _instantiatorMap.put(classname, result);
-        }
-
-        return result;
-    }
-
-    private Class findClass(String classname)
-    {
-        try
-        {
-            return _loader.loadClass(classname);
-        }
-        catch (ClassNotFoundException ex)
-        {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    /**
-     * Returns true if the package for the class name is in a package that is 
controlled by the
-     * enhancer. Controlled packages are identified by [EMAIL PROTECTED] 
#addPackage(String)}.
-     */
-
-    boolean inControlledPackage(String classname)
-    {
-        String packageName = stripTail(classname);
-
-        while (packageName != null)
-        {
-            if (_controlledPackageNames.contains(packageName))
-                return true;
-
-            packageName = stripTail(packageName);
-        }
-
-        return false;
-    }
-
-    private String stripTail(String input)
-    {
-        int lastdot = input.lastIndexOf('.');
-
-        if (lastdot < 0)
-            return null;
-
-        return input.substring(0, lastdot);
-    }
-
-    // synchronized may be overkill, but that's ok.
-    public synchronized void addPackage(String packageName)
-    {
-        Defense.notBlank(packageName, "packageName");
-
-        // TODO: Should we check that packages are not nested?
-
-        _controlledPackageNames.add(packageName);
-    }
-
-    public boolean exists(String className)
-    {
-        String path = className.replace(".", "/") + ".class";
-
-        return _parent.getResource(path) != null;
-    }
-}
+
+/**
+ * A wrapper around a Javassist class loader that allows certain classes to be 
modified as they are
+ * loaded.
+ */
+public final class ComponentInstantiatorSourceImpl extends 
InvalidationEventHubImpl implements
+        Translator, ComponentInstantiatorSource, UpdateListener
+{
+    private final Set<String> _controlledPackageNames = newSet();
+
+    private final URLChangeTracker _changeTracker = new URLChangeTracker();
+
+    private final ClassLoader _parent;
+
+    private ClassPool _classPool;
+
+    private Loader _loader;
+
+    private final ComponentClassTransformer _transformer;
+
+    private final Log _log;
+
+    /** Map from class name to Instantiator. */
+    private final Map<String, Instantiator> _instantiatorMap = newMap();
+
+    private class PackageAwareLoader extends Loader
+    {
+        public PackageAwareLoader(ClassLoader parent, ClassPool classPool)
+        {
+            super(parent, classPool);
+        }
+
+        @Override
+        protected Class findClass(String className) throws 
ClassNotFoundException
+        {
+            if (inControlledPackage(className))
+                return super.findClass(className);
+
+            // Returning null forces delegation to the parent class loader.
+
+            return null;
+        }
+
+    }
+
+    public ComponentInstantiatorSourceImpl(ClassLoader parent,
+            ComponentClassTransformer transformer, Log log)
+    {
+        _parent = parent;
+        _transformer = transformer;
+        _log = log;
+
+        initializeService();
+    }
+
+    /** @return the class loader used when loading enhanced/modified classes */
+    public ClassLoader getClassLoader()
+    {
+        return _loader;
+    }
+
+    public synchronized void checkForUpdates()
+    {
+        if (!_changeTracker.containsChanges())
+            return;
+
+        _changeTracker.clear();
+        _instantiatorMap.clear();
+
+        // Release the existing class pool, loader and so forth.
+        // Create a new one.
+
+        initializeService();
+
+        // Tell everyone that the world has changed and they should discard
+        // their cache.
+
+        fireInvalidationEvent();
+    }
+
+    /**
+     * Invoked at object creation, or when there are updates to class files 
(i.e., invalidation), to
+     * create a new set of Javassist class pools and loaders.
+     */
+    private void initializeService()
+    {
+        _classPool = new ClassPool();
+
+        ClassPath path = new LoaderClassPath(_parent);
+
+        _classPool.appendClassPath(path);
+
+        _loader = new PackageAwareLoader(_parent, _classPool);
+
+        try
+        {
+            _loader.addTranslator(_classPool, this);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    // This is called from well within a synchronized block.
+    public void onLoad(ClassPool pool, String classname) throws 
NotFoundException,
+            CannotCompileException
+    {
+        _log.debug("BEGIN onLoad " + classname);
+
+        // This is our chance to make changes to the CtClass before it is 
loaded into memory.
+
+        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.
+
+        addClassFileToChangeTracker(classname);
+
+        try
+        {
+            CtClass ctClass = pool.get(classname);
+
+            // Force the creation of the super-class before the target class.
+
+            forceSuperclassTransform(ctClass);
+
+            // Do the transformations here
+
+            _transformer.transformComponentClass(ctClass, _loader);
+
+            diag = "END";
+        }
+        catch (ClassNotFoundException ex)
+        {
+            throw new CannotCompileException(ex);
+        }
+        finally
+        {
+            _log.debug(String.format("%5s onLoad %s", diag, classname));
+        }
+    }
+
+    private void addClassFileToChangeTracker(String classname)
+    {
+        String path = classname.replace('.', '/') + ".class";
+
+        URL url = _loader.getResource(path);
+
+        _changeTracker.add(url);
+    }
+
+    private void forceSuperclassTransform(CtClass ctClass) throws 
NotFoundException,
+            ClassNotFoundException
+    {
+        CtClass superClass = ctClass.getSuperclass();
+
+        findClass(superClass.getName());
+    }
+
+    /** Does nothing. */
+    public void start(ClassPool pool) throws NotFoundException, 
CannotCompileException
+    {
+    }
+
+    public synchronized Instantiator findInstantiator(String classname)
+    {
+        Instantiator result = _instantiatorMap.get(classname);
+
+        if (result == null)
+        {
+            Class instanceClass = findClass(classname);
+
+            result = _transformer.createInstantiator(instanceClass);
+
+            _instantiatorMap.put(classname, result);
+        }
+
+        return result;
+    }
+
+    private Class findClass(String classname)
+    {
+        try
+        {
+            return _loader.loadClass(classname);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Returns true if the package for the class name is in a package that is 
controlled by the
+     * enhancer. Controlled packages are identified by [EMAIL PROTECTED] 
#addPackage(String)}.
+     */
+
+    boolean inControlledPackage(String classname)
+    {
+        String packageName = stripTail(classname);
+
+        while (packageName != null)
+        {
+            if (_controlledPackageNames.contains(packageName))
+                return true;
+
+            packageName = stripTail(packageName);
+        }
+
+        return false;
+    }
+
+    private String stripTail(String input)
+    {
+        int lastdot = input.lastIndexOf('.');
+
+        if (lastdot < 0)
+            return null;
+
+        return input.substring(0, lastdot);
+    }
+
+    // synchronized may be overkill, but that's ok.
+    public synchronized void addPackage(String packageName)
+    {
+        Defense.notBlank(packageName, "packageName");
+
+        // TODO: Should we check that packages are not nested?
+
+        _controlledPackageNames.add(packageName);
+    }
+
+    public boolean exists(String className)
+    {
+        String path = className.replace(".", "/") + ".class";
+
+        return _parent.getResource(path) != null;
+    }
+}

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt?view=diff&rev=479391&r1=479390&r2=479391
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt 
(original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt 
Sun Nov 26 10:25:21 2006
@@ -4,6 +4,12 @@
  
 Component Classes
 
+  Component classes in Tapestry 5 are much easier than in Tapestry 4.  There 
are no base classes to extend from, the classes are concrete (not abstract), 
and there's no XML file. There is still
+  a bit of configuration in the form of Java annotations, but
+  those now go directly onto fields of your class, rather than on abstract 
getters and setters (the case in Tapestry 4).  
+  
+  Classes for pages, for components and for component mixins are all created 
in an identical way.
+
 * Component Class Basics
 
   Creating page and component classes in Tapestry 5 is a breeze.
@@ -50,6 +56,29 @@
  
   In another departure from Tapestry 4, these methods are not necessarily 
public; they
   can have any visibility you like.
+  
+Component Packages
+
+  Component classes must exist within an appropriate package (this is 
necessary for runtime code transformation
+  and class reloading to operate).
+  
+  These packages exist under the application's root package.
+  
+  For pages, place classes in <root>.<<pages>>.  Page names are mapped to 
classes within this package.
+  
+  For components, place classes in <root>.<<components>>.  Component types are 
mapped to classes within this package.
+  
+  For mixins, place classes in <root>.<<mixins>>.   Mixin types are mapped to 
classes within this package.
+  
+  In addition, it is common for an application to have base classes, often 
<abstract> base classes, that should not be directly referenced. These
+  should not go in the <<pages>>, <<components>> or <<mixins>> packages, 
because they then look like valid pages, components or mixins. Instead,
+  use the <root>.<<base>> package to store such base classes.
+  
+Sub-Folders / Sub-Packages
+
+  Classes do not have to go directly inside the package (pages, components, 
mixins, etc.). It is valid to create a sub-package 
+  to store some of the classes.  The sub-package name becomes part of the page 
name or component type.  Thus you might define a page component 
+  <<<com.example.myapp.pages.admin.CreateUser>>> and the logical page name 
(which often shows up inside URLs) will be <<admin/CreateUser>>.
   
 Pages vs. Components
 

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentClassResolverImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentClassResolverImplTest.java?view=diff&rev=479391&r1=479390&r2=479391
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentClassResolverImplTest.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentClassResolverImplTest.java
 Sun Nov 26 10:25:21 2006
@@ -401,6 +401,7 @@
         source.addPackage(packageName + ".pages");
         source.addPackage(packageName + ".components");
         source.addPackage(packageName + ".mixins");
+        source.addPackage(packageName + ".base");
     }
 
     /**


Reply via email to