You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2007/03/05 00:40:53 UTC

svn commit: r514498 - in /tapestry/tapestry4/trunk: tapestry-examples/TimeTracker/ tapestry-framework/src/java/org/apache/tapestry/enhance/ tapestry-framework/src/java/org/apache/tapestry/services/impl/

Author: jkuhnert
Date: Sun Mar  4 15:40:52 2007
New Revision: 514498

URL: http://svn.apache.org/viewvc?view=rev&rev=514498
Log:
Various enhancements to reduce the overall memory footprint when dealing with the new compiled ognl expressions.

Added:
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/AbstractFab.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryClassLoader.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/CtClassSource.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/HiveMindClassPool.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/InterfaceFabImpl.java
Modified:
    tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/pom.xml
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFabImpl.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryImpl.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceMessages.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceStrings.properties
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/MethodFabImpl.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/HiveMindExpressionCompiler.java

Modified: tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/pom.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/pom.xml?view=diff&rev=514498&r1=514497&r2=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/pom.xml (original)
+++ tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/pom.xml Sun Mar  4 15:40:52 2007
@@ -111,7 +111,7 @@
                     <systemProperties>
                         <systemProperty>
                             <name>org.apache.tapestry.disable-caching</name>
-                            <value>true</value>
+                            <value>false</value>
                         </systemProperty>
                     </systemProperties>
                 </configuration>

Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/AbstractFab.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/AbstractFab.java?view=auto&rev=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/AbstractFab.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/AbstractFab.java Sun Mar  4 15:40:52 2007
@@ -0,0 +1,109 @@
+// Copyright 2004, 2005 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.tapestry.enhance;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javassist.CtClass;
+
+/**
+ * Common code for {@link org.apache.hivemind.service.impl.ClassFabImpl} and
+ * {@link org.apache.hivemind.service.impl.InterfaceFabImpl}.
+ * 
+ * @author Howard M. Lewis Ship
+ * @since 1.1
+ */
+public class AbstractFab
+{
+
+    private final CtClass _ctClass;
+
+    private final CtClassSource _source;
+
+    /**
+     * Map from Class to CtClass.
+     * 
+     * @since 1.1
+     */
+    private Map _ctClassCache = new HashMap();
+    
+    public AbstractFab(CtClassSource source, CtClass ctClass)
+    {
+        _ctClass = ctClass;
+        _source = source;
+    }
+
+    public void addInterface(Class interfaceClass)
+    {
+        CtClass ctInterfaceClass = _source.getCtClass(interfaceClass);
+
+        _ctClass.addInterface(ctInterfaceClass);
+    }
+
+    protected CtClass[] convertClasses(Class[] inputClasses)
+    {
+        if (inputClasses == null || inputClasses.length == 0)
+            return null;
+
+        int count = inputClasses.length;
+        CtClass[] result = new CtClass[count];
+
+        for (int i = 0; i < count; i++)
+        {
+            CtClass ctClass = convertClass(inputClasses[i]);
+
+            result[i] = ctClass;
+        }
+
+        return result;
+    }
+
+    /**
+     * @since 1.1
+     */
+    protected CtClass convertClass(Class inputClass)
+    {
+        CtClass result = (CtClass) _ctClassCache.get(inputClass);
+
+        if (result == null)
+        {
+            result = _source.getCtClass(inputClass);
+            _ctClassCache.put(inputClass, result);
+        }
+
+        return result;
+    }
+
+    public Class createClass()
+    {
+        return _source.createClass(_ctClass);
+    }
+
+    public Class createClass(boolean detach)
+    {
+        return _source.createClass(_ctClass, detach);
+    }
+    
+    protected CtClass getCtClass()
+    {
+        return _ctClass;
+    }
+
+    protected CtClassSource getSource()
+    {
+        return _source;
+    }
+
+}

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFabImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFabImpl.java?view=diff&rev=514498&r1=514497&r2=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFabImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFabImpl.java Sun Mar  4 15:40:52 2007
@@ -31,8 +31,6 @@
 import org.apache.hivemind.service.ClassFab;
 import org.apache.hivemind.service.MethodFab;
 import org.apache.hivemind.service.MethodSignature;
-import org.apache.hivemind.service.impl.AbstractFab;
-import org.apache.hivemind.service.impl.CtClassSource;
 
 /**
  * Implementation replacement for hivemind {@link ClassFab} utiltity to get around some javassist
@@ -50,7 +48,6 @@
 
     private class AddedConstructor
     {
-
         private Class[] _parameterTypes;
 
         private Class[] _exceptionTypes;

Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryClassLoader.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryClassLoader.java?view=auto&rev=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryClassLoader.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryClassLoader.java Sun Mar  4 15:40:52 2007
@@ -0,0 +1,72 @@
+// Copyright 2004, 2005 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.tapestry.enhance;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * ClassLoader used to properly instantiate newly created classes.
+ * 
+ * @author Howard Lewis Ship / Essl Christian
+ * @see org.apache.hivemind.service.impl.CtClassSource
+ */
+class ClassFactoryClassLoader extends ClassLoader
+{
+    private List _loaders = new ArrayList();
+
+    /**
+     * Adds a delegate class loader to the list of delegate class loaders.
+     */
+    public synchronized void addDelegateLoader(ClassLoader loader)
+    {
+        _loaders.add(loader);
+    }
+
+    /**
+     * Searches each of the delegate class loaders for the given class.
+     */
+    protected synchronized Class findClass(String name) throws ClassNotFoundException
+    {
+        ClassNotFoundException cnfex = null;
+        
+        try
+        {
+            return super.findClass(name);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            cnfex = ex;
+        }
+
+        int count = _loaders.size();
+        for (int i = 0; i < count; i++)
+        {
+            ClassLoader l = (ClassLoader) _loaders.get(i);
+
+            try
+            {
+                return l.loadClass(name);
+            }
+            catch (ClassNotFoundException ex)
+            {
+                //
+            }
+        }
+        
+        // Not found .. throw the first exception
+
+        throw cnfex;
+    }
+}

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryImpl.java?view=diff&rev=514498&r1=514497&r2=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/ClassFactoryImpl.java Sun Mar  4 15:40:52 2007
@@ -19,9 +19,6 @@
 import org.apache.hivemind.service.ClassFab;
 import org.apache.hivemind.service.ClassFactory;
 import org.apache.hivemind.service.InterfaceFab;
-import org.apache.hivemind.service.impl.CtClassSource;
-import org.apache.hivemind.service.impl.HiveMindClassPool;
-import org.apache.hivemind.service.impl.InterfaceFabImpl;
 
 /**
  * Implementation of the hivemind core {@link ClassFactory} service to get around some incompatibilities 
@@ -31,6 +28,8 @@
  */
 public class ClassFactoryImpl implements ClassFactory
 {
+    static final int EXPIRED_CLASS_COUNT = 100;
+    
     /**
      * ClassPool shared by all modules (all CtClassSource instances).
      */
@@ -38,10 +37,14 @@
 
     private CtClassSource _classSource = new CtClassSource(_pool);
 
+    private int _classCounter = 0;
+    
     public ClassFab newClass(String name, Class superClass)
     {
         try
         {
+            checkPoolExpiration();
+            
             CtClass ctNewClass = _classSource.newClass(name, superClass);
             
             return new ClassFabImpl(_classSource, ctNewClass);
@@ -61,6 +64,8 @@
     {
         try
         {
+            checkPoolExpiration();
+            
             CtClass ctNewClass = _classSource.newInterface(name);
 
             return new InterfaceFabImpl(_classSource, ctNewClass);
@@ -71,5 +76,18 @@
                     EnhanceMessages.unableToCreateInterface(name, ex), ex);
         }
 
+    }
+    
+    void checkPoolExpiration()
+    {
+        _classCounter++;
+        
+        synchronized(_classSource) {
+            if (_classCounter >= EXPIRED_CLASS_COUNT) {
+                _pool.clearImportedPackages();
+                
+                _classCounter = 0;
+            }
+        }
     }
 }

Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/CtClassSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/CtClassSource.java?view=auto&rev=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/CtClassSource.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/CtClassSource.java Sun Mar  4 15:40:52 2007
@@ -0,0 +1,99 @@
+// Copyright 2004, 2005 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.tapestry.enhance;
+
+import javassist.CtClass;
+import javassist.NotFoundException;
+
+import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.service.ClassFabUtils;
+
+/**
+ * Wrapper around Javassist's {@link javassist.ClassPool} and our own
+ * {@link org.apache.hivemind.service.impl.ClassFactoryClassLoader} that manages the creation of new
+ * instance of {@link javassist.CtClass} and converts finished CtClass's into instantiable Classes.
+ * 
+ * @author Howard Lewis Ship
+ */
+public class CtClassSource
+{
+    private HiveMindClassPool _pool;
+    
+    public CtClassSource(HiveMindClassPool pool)
+    {
+        _pool = pool;
+    }
+
+    public CtClass getCtClass(Class searchClass)
+    {
+        ClassLoader loader = searchClass.getClassLoader();
+
+        // Add the class loader for the searchClass to the class pool and
+        // delegating class loader if needed.
+
+        _pool.appendClassLoader(loader);
+
+        String name = ClassFabUtils.getJavaClassName(searchClass);
+
+        try
+        {
+            return _pool.get(name);
+        }
+        catch (NotFoundException ex)
+        {
+            throw new ApplicationRuntimeException(EnhanceMessages.unableToLookupClass(name, ex), ex);
+        }
+    }
+
+    public CtClass newClass(String name, Class superClass)
+    {
+        CtClass ctSuperClass = getCtClass(superClass);
+
+        return _pool.makeClass(name, ctSuperClass);
+    }
+
+    /**
+     * Creates a new, empty interace, with the given name.
+     * 
+     * @since 1.1
+     */
+
+    public CtClass newInterface(String name)
+    {
+        return _pool.makeInterface(name);
+    }
+
+    public Class createClass(CtClass ctClass)
+    {
+        return createClass(ctClass, false);
+    }
+    
+    public Class createClass(CtClass ctClass, boolean detach)
+    {
+        try
+        {
+            return _pool.toClass(ctClass, detach);
+        }
+        catch (Throwable ex)
+        {
+            throw new ApplicationRuntimeException(EnhanceMessages.unableToWriteClass(ctClass, ex),
+                    ex);
+        }
+    }
+    
+    public void setPool(HiveMindClassPool pool)
+    {
+        _pool = pool;
+    }
+}

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceMessages.java?view=diff&rev=514498&r1=514497&r2=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceMessages.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceMessages.java Sun Mar  4 15:40:52 2007
@@ -183,6 +183,16 @@
         return _formatter.format("unable-to-add-field", fieldName, ctClass.getName(), cause);
     }
     
+    static String unableToLookupClass(String name, Throwable cause)
+    {
+        return _formatter.format("unable-to-lookup", name, cause);
+    }
+    
+    static String unableToWriteClass(CtClass ctClass, Throwable cause)
+    {
+        return _formatter.format("unable-to-write-class", ctClass.getName(), cause);
+    }
+    
     static String duplicateMethodInClass(MethodSignature ms, ClassFabImpl cf)
     {
         return _formatter.format("duplicate-method-in-class", ms, cf.getName());

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceStrings.properties?view=diff&rev=514498&r1=514497&r2=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceStrings.properties (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/EnhanceStrings.properties Sun Mar  4 15:40:52 2007
@@ -41,3 +41,5 @@
 duplicate-method-in-class=Attempt to redefine method {0} of class {1}.
 unable-to-add-catch=Unable to add catch block for exception {0} to class {1}: {2}
 unable-to-extend-method=Unable to extend method {0} of class {1}: {2}
+unable-to-lookup=Unable to lookup {0}: {1}
+unable-to-write-class=Unable to create class {0}: {1}

Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/HiveMindClassPool.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/HiveMindClassPool.java?view=auto&rev=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/HiveMindClassPool.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/HiveMindClassPool.java Sun Mar  4 15:40:52 2007
@@ -0,0 +1,91 @@
+// Copyright 2007 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.tapestry.enhance;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javassist.CannotCompileException;
+import javassist.ClassPath;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.LoaderClassPath;
+
+/**
+ * Used to ensure that {@link javassist.ClassPool#appendClassPath(javassist.ClassPath)} is invoked
+ * with a synchronized lock. Additionally, wraps around a shared
+ * {@link org.apache.hivemind.service.impl.ClassFactoryClassLoader}.
+ * 
+ * @author Howard Lewis Ship
+ */
+public class HiveMindClassPool extends ClassPool
+{
+    private ClassFactoryClassLoader _loader = new ClassFactoryClassLoader();
+    
+    /**
+     * Used to identify which class loaders have already been integrated into the pool.
+     */
+    private Set _loaders = new HashSet();
+
+    public HiveMindClassPool()
+    {
+        super(null);
+
+        appendClassLoader(Thread.currentThread().getContextClassLoader());
+    }
+
+    /**
+     * Convienience method for adding to the ClassPath for a particular class loader.
+     */
+    public synchronized void appendClassLoader(ClassLoader loader)
+    {
+        if (loader == null || loader == _loader || _loaders.contains(loader))
+            return;
+
+        _loader.addDelegateLoader(loader);
+        
+        ClassPath path = new LoaderClassPath(loader);
+
+        appendClassPath(path);
+
+        _loaders.add(loader);
+    }
+
+    /**
+     * Invoked to convert an fabricated class into a real class. The new classes' class loader will
+     * be the delegating ClassFactoryClassLoader, which has visibility to all class loaders for all
+     * modules.
+     * 
+     * @since 1.1
+     */
+    public Class toClass(CtClass ctClass) throws CannotCompileException
+    {
+        return toClass(ctClass, false);
+    }
+    
+    public Class toClass(CtClass ctClass, boolean detach) throws CannotCompileException
+    {
+        Class clazz = ctClass.toClass(_loader, getClass().getProtectionDomain());
+        
+        if (detach)
+            ctClass.detach();
+        
+        return clazz;
+    }
+    
+    public Set getLoaders()
+    {
+        return _loaders;
+    }
+}

Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/InterfaceFabImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/InterfaceFabImpl.java?view=auto&rev=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/InterfaceFabImpl.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/InterfaceFabImpl.java Sun Mar  4 15:40:52 2007
@@ -0,0 +1,111 @@
+// Copyright 2004, 2005 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.tapestry.enhance;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javassist.CtClass;
+import javassist.CtMethod;
+
+import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.service.InterfaceFab;
+import org.apache.hivemind.service.MethodSignature;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class InterfaceFabImpl extends AbstractFab implements InterfaceFab
+{
+    private List _methods = new ArrayList();
+
+    public InterfaceFabImpl(CtClassSource source, CtClass ctClass)
+    {
+        super(source, ctClass);
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer("InterfaceFabImpl[\npublic interface ");
+
+        CtClass ctClass = getCtClass();
+
+        buffer.append(ctClass.getName());
+
+        try
+        {
+            CtClass[] interfaces = ctClass.getInterfaces();
+
+            for (int i = 0; i < interfaces.length; i++)
+            {
+                buffer.append(i == 0 ? " extends " : ", ");
+                buffer.append(interfaces[i].getName());
+            }
+
+        }
+        catch (Exception ex)
+        {
+            buffer.append("<Exception: " + ex + ">");
+        }
+
+        Iterator i = _methods.iterator();
+
+        while (i.hasNext())
+        {
+            MethodSignature sig = (MethodSignature) i.next();
+
+            buffer.append("\n\npublic ");
+            buffer.append(sig);
+            buffer.append(";");
+        }
+
+        buffer.append("\n]");
+
+        return buffer.toString();
+    }
+
+    public void addMethod(MethodSignature ms)
+    {
+        CtClass ctReturnType = convertClass(ms.getReturnType());
+        CtClass[] ctParameters = convertClasses(ms.getParameterTypes());
+        CtClass[] ctExceptions = convertClasses(ms.getExceptionTypes());
+
+        CtMethod method = new CtMethod(ctReturnType, ms.getName(), ctParameters, getCtClass());
+
+        try
+        {
+            method.setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT);
+            method.setExceptionTypes(ctExceptions);
+
+            getCtClass().addMethod(method);
+        }
+        catch (Exception ex)
+        {
+            throw new ApplicationRuntimeException(EnhanceMessages.unableToAddMethod(
+                    ms,
+                    getCtClass(),
+                    ex), ex);
+        }
+
+        _methods.add(ms);
+    }
+
+    public Class createInterface()
+    {
+        return createClass();
+    }
+
+}

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/MethodFabImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/MethodFabImpl.java?view=diff&rev=514498&r1=514497&r2=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/MethodFabImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/enhance/MethodFabImpl.java Sun Mar  4 15:40:52 2007
@@ -21,7 +21,6 @@
 import org.apache.hivemind.ApplicationRuntimeException;
 import org.apache.hivemind.service.MethodFab;
 import org.apache.hivemind.service.MethodSignature;
-import org.apache.hivemind.service.impl.CtClassSource;
 
 /**
  * Implementation of hivemind {@link MethodFab} utiltity.

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/HiveMindExpressionCompiler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/HiveMindExpressionCompiler.java?view=diff&rev=514498&r1=514497&r2=514498
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/HiveMindExpressionCompiler.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/HiveMindExpressionCompiler.java Sun Mar  4 15:40:52 2007
@@ -46,6 +46,7 @@
 import org.apache.hivemind.service.ClassFactory;
 import org.apache.hivemind.service.MethodSignature;
 import org.apache.tapestry.IRender;
+import org.apache.tapestry.enhance.AbstractFab;
 
 /**
  * Adds to default ognl compiler class pools.
@@ -186,9 +187,7 @@
             return;
 
         synchronized (expression) {
-
-
-
+            
             String getBody = null;
             String setBody = null;
 
@@ -244,7 +243,7 @@
 
                 classFab.addConstructor(new Class[0], new Class[0], "{}");
 
-                Class clazz = classFab.createClass();
+                Class clazz = ((AbstractFab)classFab).createClass(true);
 
                 expression.setAccessor((ExpressionAccessor)clazz.newInstance());