You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2012/05/25 22:59:11 UTC

git commit: Cache result of determining method/constructor location - another hotspot found in high volume applications

Updated Branches:
  refs/heads/master 8224aae21 -> 9b4a8e12b


Cache result of determining method/constructor location
- another hotspot found in high volume applications


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/9b4a8e12
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/9b4a8e12
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/9b4a8e12

Branch: refs/heads/master
Commit: 9b4a8e12b04d9c9ace2a0817cccf6fa541aafae3
Parents: 8224aae
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Fri May 25 13:58:49 2012 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Fri May 25 13:58:49 2012 -0700

----------------------------------------------------------------------
 .../services/ComponentInstantiatorSourceImpl.java  |    3 +-
 .../apache/tapestry5/services/TapestryModule.java  |   26 ++++-
 .../internal/AbstractReloadableObjectCreator.java  |   10 ++-
 .../tapestry5/ioc/internal/RegistryImpl.java       |    2 +-
 .../ioc/internal/ReloadableObjectCreator.java      |    7 +-
 .../internal/ReloadableObjectCreatorSource.java    |    6 +-
 ...loadableServiceImplementationObjectCreator.java |   13 ++-
 .../internal/services/PlasticProxyFactoryImpl.java |   79 ++++++++++++---
 .../ioc/services/PlasticProxyFactory.java          |   35 +++++--
 9 files changed, 136 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b4a8e12/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
index 8e8b281..6a0f591 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2010, 2011 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2010, 2011, 2012 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.
@@ -168,6 +168,7 @@ public final class ComponentInstantiatorSourceImpl implements ComponentInstantia
     {
         changeTracker.clear();
         classToInstantiator.clear();
+        proxyFactory.clearCache();
 
         // Release the existing class pool, loader and so forth.
         // Create a new one.

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b4a8e12/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
index 9fde12c..87696f5 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
@@ -1229,9 +1229,10 @@ public final class TapestryModule
      * href="https://issues.apache.org/jira/browse/TAP5-79">TAP5-79</a> for details. There are no longer any built-in
      * contributions to the configuration.
      *
-     * @param configuration contributions of special factories for some constants, each
-     *                      contributed factory may return a
-     *                      binding if applicable, or null otherwise
+     * @param configuration
+     *         contributions of special factories for some constants, each
+     *         contributed factory may return a
+     *         binding if applicable, or null otherwise
      */
     public BindingFactory buildPropBindingFactory(List<BindingFactory> configuration, @Autobuild
     PropBindingFactory service)
@@ -2195,7 +2196,8 @@ public final class TapestryModule
      * <p/>
      * This contributes "class", "properties" and "tml" (the template extension).
      *
-     * @param configuration collection of extensions
+     * @param configuration
+     *         collection of extensions
      */
     public static void contributeResourceDigestGenerator(Configuration<String> configuration)
     {
@@ -2664,7 +2666,8 @@ public final class TapestryModule
      * even if a user overrides the default
      * service implementation.
      *
-     * @param defaultSource The service to decorate
+     * @param defaultSource
+     *         The service to decorate
      * @param environment
      */
     public static FieldValidatorDefaultSource decorateFieldValidatorDefaultSource(
@@ -2868,4 +2871,17 @@ public final class TapestryModule
     {
         configuration.add("LocalhostOnly", new LocalhostOnly());
     }
+
+    @Startup
+    public static void registerToClearPlasticProxyFactoryOnInvalidation(@ComponentClasses InvalidationEventHub hub, @Builtin final PlasticProxyFactory proxyFactory)
+    {
+        hub.addInvalidationListener(new InvalidationListener()
+        {
+            @Override
+            public void objectWasInvalidated()
+            {
+                proxyFactory.clearCache();
+            }
+        });
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b4a8e12/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java
index ed69717..0bd464d 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java
@@ -1,4 +1,4 @@
-// Copyright 2010, 2011 The Apache Software Foundation
+// Copyright 2010, 2011, 2012 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.
@@ -28,6 +28,7 @@ import org.apache.tapestry5.ioc.ReloadAware;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.internal.util.URLChangeTracker;
+import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.apache.tapestry5.services.UpdateListener;
 import org.slf4j.Logger;
 
@@ -51,6 +52,8 @@ public abstract class AbstractReloadableObjectCreator implements ObjectCreator,
 
     private final URLChangeTracker changeTracker = new URLChangeTracker();
 
+    private final PlasticProxyFactory proxyFactory;
+
     /**
      * The set of class names that should be loaded by the class loader. This is necessary to support
      * reloading the class when a base class changes, and to properly support access to protected methods.
@@ -63,9 +66,10 @@ public abstract class AbstractReloadableObjectCreator implements ObjectCreator,
 
     private PlasticClassLoader loader;
 
-    protected AbstractReloadableObjectCreator(ClassLoader baseClassLoader, String implementationClassName,
+    protected AbstractReloadableObjectCreator(PlasticProxyFactory proxyFactory, ClassLoader baseClassLoader, String implementationClassName,
                                               Logger logger, OperationTracker tracker)
     {
+        this.proxyFactory = proxyFactory;
         this.baseClassLoader = baseClassLoader;
         this.implementationClassName = implementationClassName;
         this.logger = logger;
@@ -89,6 +93,8 @@ public abstract class AbstractReloadableObjectCreator implements ObjectCreator,
 
         loader = null;
 
+        proxyFactory.clearCache();
+
         boolean reloadNow = informInstanceOfReload();
 
         instance = reloadNow ? createInstance() : null;

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b4a8e12/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
index 7eb0906..d618341 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
@@ -1079,7 +1079,7 @@ public class RegistryImpl implements Registry, InternalRegistry, ServiceProxyPro
     private <T> T createReloadingProxy(Class<T> interfaceClass, final Class<? extends T> implementationClass,
                                        ObjectLocator locator)
     {
-        ReloadableObjectCreator creator = new ReloadableObjectCreator(implementationClass.getClassLoader(),
+        ReloadableObjectCreator creator = new ReloadableObjectCreator(proxyFactory, implementationClass.getClassLoader(),
                 implementationClass.getName(), loggerSource.getLogger(implementationClass), this, locator);
 
         getService(UpdateListenerHub.class).addUpdateListener(creator);

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b4a8e12/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java
index 48c802b..b54da52 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2012 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.
@@ -16,6 +16,7 @@ package org.apache.tapestry5.ioc.internal;
 
 import org.apache.tapestry5.ioc.ObjectLocator;
 import org.apache.tapestry5.ioc.OperationTracker;
+import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.slf4j.Logger;
 
 /**
@@ -25,10 +26,10 @@ public class ReloadableObjectCreator extends AbstractReloadableObjectCreator
 {
     private final ObjectLocator locator;
 
-    public ReloadableObjectCreator(ClassLoader baseClassLoader, String implementationClassName, Logger logger,
+    public ReloadableObjectCreator(PlasticProxyFactory proxyFactory, ClassLoader baseClassLoader, String implementationClassName, Logger logger,
             OperationTracker tracker, ObjectLocator locator)
     {
-        super(baseClassLoader, implementationClassName, logger, tracker);
+        super(proxyFactory, baseClassLoader, implementationClassName, logger, tracker);
 
         this.locator = locator;
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b4a8e12/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java
index 8e5dd82..2bf35f7 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java
@@ -1,4 +1,4 @@
-// Copyright 2010, 2011 The Apache Software Foundation
+// Copyright 2010, 2011, 2012 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.
@@ -73,13 +73,15 @@ public class ReloadableObjectCreatorSource implements ObjectCreatorSource
 
     private Object createReloadableProxy(ServiceBuilderResources resources)
     {
-        ReloadableServiceImplementationObjectCreator reloadableCreator = new ReloadableServiceImplementationObjectCreator(
+        ReloadableServiceImplementationObjectCreator reloadableCreator = new ReloadableServiceImplementationObjectCreator(proxyFactory,
                 resources, proxyFactory.getClassLoader(), serviceImplementationClass.getName());
 
         resources.getService(UpdateListenerHub.class).addUpdateListener(reloadableCreator);
 
         if (eagerLoad)
+        {
             reloadableCreator.createObject();
+        }
 
         return proxyFactory.createProxy(serviceInterfaceClass, reloadableCreator, getDescription());
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b4a8e12/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableServiceImplementationObjectCreator.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableServiceImplementationObjectCreator.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableServiceImplementationObjectCreator.java
index 31611eb..93baf33 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableServiceImplementationObjectCreator.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableServiceImplementationObjectCreator.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2012 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.
@@ -14,11 +14,12 @@
 
 package org.apache.tapestry5.ioc.internal;
 
-import java.lang.reflect.Constructor;
-
 import org.apache.tapestry5.ioc.ObjectCreator;
 import org.apache.tapestry5.ioc.ServiceBuilderResources;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
+
+import java.lang.reflect.Constructor;
 
 /**
  * Returns an {@link ObjectCreator} for lazily instantiating a given implementation class (with dependencies).
@@ -30,10 +31,10 @@ public class ReloadableServiceImplementationObjectCreator extends AbstractReload
 {
     private final ServiceBuilderResources resources;
 
-    public ReloadableServiceImplementationObjectCreator(ServiceBuilderResources resources, ClassLoader baseClassLoader,
-            String implementationClassName)
+    public ReloadableServiceImplementationObjectCreator(PlasticProxyFactory proxyFactory, ServiceBuilderResources resources, ClassLoader baseClassLoader,
+                                                        String implementationClassName)
     {
-        super(baseClassLoader, implementationClassName, resources.getLogger(), resources.getTracker());
+        super(proxyFactory, baseClassLoader, implementationClassName, resources.getLogger(), resources.getTracker());
 
         this.resources = resources;
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b4a8e12/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
index 440078b..45bf82e 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2011 The Apache Software Foundation
+// Copyright 2011, 2012 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.
@@ -19,6 +19,7 @@ import org.apache.tapestry5.internal.plastic.asm.Type;
 import org.apache.tapestry5.internal.plastic.asm.tree.*;
 import org.apache.tapestry5.ioc.Location;
 import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.apache.tapestry5.plastic.*;
@@ -28,11 +29,14 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.util.List;
+import java.util.Map;
 
 public class PlasticProxyFactoryImpl implements PlasticProxyFactory
 {
     private final PlasticManager manager;
 
+    private final Map<String, Location> memberToLocation = CollectionFactory.newConcurrentMap();
+
     public PlasticProxyFactoryImpl(ClassLoader parentClassLoader, Logger logger)
     {
         this(PlasticManager.withClassLoader(parentClassLoader).create(), logger);
@@ -109,35 +113,78 @@ public class PlasticProxyFactoryImpl implements PlasticProxyFactory
         return bytecode == null ? null : PlasticInternalUtils.convertBytecodeToClassNode(bytecode);
     }
 
-    public Location getMethodLocation(Method method)
+    public Location getMethodLocation(final Method method)
     {
+        ObjectCreator<String> descriptionCreator = new ObjectCreator<String>()
+        {
+            @Override
+            public String createObject()
+            {
+                return InternalUtils.asString(method);
+            }
+        };
+
         return getMemberLocation(method, method.getName(), Type.getMethodDescriptor(method),
-                InternalUtils.asString(method));
+                descriptionCreator);
     }
 
-    public Location getConstructorLocation(Constructor constructor)
+    public Location getConstructorLocation(final Constructor constructor)
     {
-        StringBuilder builder = new StringBuilder(constructor.getDeclaringClass().getName()).append("(");
-        String sep = "";
-
-        for (Class parameterType : constructor.getParameterTypes())
+        ObjectCreator<String> descriptionCreator = new ObjectCreator<String>()
         {
-            builder.append(sep);
-            builder.append(parameterType.getSimpleName());
+            @Override
+            public String createObject()
+            {
+                StringBuilder builder = new StringBuilder(constructor.getDeclaringClass().getName()).append("(");
+                String sep = "";
 
-            sep = ", ";
-        }
+                for (Class parameterType : constructor.getParameterTypes())
+                {
+                    builder.append(sep);
+                    builder.append(parameterType.getSimpleName());
 
-        builder.append(")");
+                    sep = ", ";
+                }
 
-        String constructorDescription = builder.toString();
+                builder.append(")");
+
+                return builder.toString();
+            }
+        };
 
         return getMemberLocation(constructor, "<init>", Type.getConstructorDescriptor(constructor),
-                constructorDescription);
+                descriptionCreator);
+    }
+
+    @Override
+    public void clearCache()
+    {
+        memberToLocation.clear();
+    }
+
+
+    public Location getMemberLocation(Member member, String methodName, String memberTypeDesc, ObjectCreator<String> textDescriptionCreator)
+    {
+        String className = member.getDeclaringClass().getName();
+
+        String key = className + ":" + methodName + ":" + memberTypeDesc;
+
+        Location location = memberToLocation.get(key);
+
+        if (location == null)
+        {
+            location = constructMemberLocation(member, methodName, memberTypeDesc, textDescriptionCreator.createObject());
+
+            memberToLocation.put(key, location);
+        }
+
+        return location;
+
     }
 
-    public Location getMemberLocation(Member member, String methodName, String memberTypeDesc, String textDescription)
+    private Location constructMemberLocation(Member member, String methodName, String memberTypeDesc, String textDescription)
     {
+
         ClassNode classNode = readClassNode(member.getDeclaringClass());
 
         if (classNode == null)

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b4a8e12/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java
index e8099c3..81e1eac 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java
@@ -1,4 +1,4 @@
-// Copyright 2011 The Apache Software Foundation
+// Copyright 2011, 2012 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.
@@ -42,8 +42,10 @@ public interface PlasticProxyFactory extends PlasticClassListenerHub
      * Creates a proxy object that implements the indicated interface, then invokes the callback to further
      * configure the proxy.
      *
-     * @param interfaceType interface implemented by proxy
-     * @param callback      configures the proxy
+     * @param interfaceType
+     *         interface implemented by proxy
+     * @param callback
+     *         configures the proxy
      * @return instantiator that can be used to create an instance of the proxy class
      */
     <T> ClassInstantiator<T> createProxy(Class<T> interfaceType, PlasticClassTransformer callback);
@@ -53,7 +55,8 @@ public interface PlasticProxyFactory extends PlasticClassListenerHub
      * used in the cases where encapsulating the PlasticClass construction into a {@linkplain PlasticClassTransformer
      * callback} is not feasible (which is the case for some of the older APIs inside Tapestry IoC).
      *
-     * @param interfaceType class proxy will extend from
+     * @param interfaceType
+     *         class proxy will extend from
      * @return transformation from which an instantiator may be created
      */
     <T> PlasticClassTransformation<T> createProxyTransformation(Class<T> interfaceType);
@@ -64,10 +67,14 @@ public interface PlasticProxyFactory extends PlasticClassListenerHub
      * creator implementation may decide to
      * cache the return value as appropriate).
      *
-     * @param <T>           type of proxy
-     * @param interfaceType interface class for proxy
-     * @param creator       object responsible for creating the real object
-     * @param description   the <code>toString()</code> of the proxy
+     * @param <T>
+     *         type of proxy
+     * @param interfaceType
+     *         interface class for proxy
+     * @param creator
+     *         object responsible for creating the real object
+     * @param description
+     *         the <code>toString()</code> of the proxy
      * @return proxy instance
      */
     <T> T createProxy(Class<T> interfaceType, ObjectCreator<T> creator, String description);
@@ -75,7 +82,8 @@ public interface PlasticProxyFactory extends PlasticClassListenerHub
     /**
      * Converts a method to a {@link Location}, which includes information about the source file name and line number.
      *
-     * @param method to look up
+     * @param method
+     *         to look up
      * @return the location (identifying the method and possibly, the line number within the method)
      */
     Location getMethodLocation(Method method);
@@ -87,4 +95,13 @@ public interface PlasticProxyFactory extends PlasticClassListenerHub
      * @return the location (identifying the constructor and possibly, the line number within the method)
      */
     Location getConstructorLocation(Constructor constructor);
+
+    /**
+     * Clears any cached information stored by the proxy factory; this is useful in Tapestry development mode
+     * when a class loader may have been discarded (because the proxy factory may indirectly keep references
+     * to classes loaded by the old class loader).
+     *
+     * @since 5.3.3
+     */
+    void clearCache();
 }