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 2010/04/21 11:45:20 UTC

svn commit: r936231 - in /tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services: ComponentClassTransformerImpl.java InternalClassTransformation.java InternalClassTransformationImpl.java

Author: hlship
Date: Wed Apr 21 09:45:20 2010
New Revision: 936231

URL: http://svn.apache.org/viewvc?rev=936231&view=rev
Log:
TAP5-1110: Tapestry holds onto the verbose descriptions of component class transformations, causing a memory leak

Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassTransformerImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassTransformerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassTransformerImpl.java?rev=936231&r1=936230&r2=936231&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassTransformerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassTransformerImpl.java Wed Apr 21 09:45:20 2010
@@ -4,7 +4,7 @@
 // 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
+// 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,
@@ -44,7 +44,8 @@ public class ComponentClassTransformerIm
     /**
      * Map from class name to class transformation.
      */
-    private final Map<String, InternalClassTransformation> nameToClassTransformation = CollectionFactory.newConcurrentMap();
+    private final Map<String, InternalClassTransformation> nameToClassTransformation = CollectionFactory
+            .newConcurrentMap();
 
     private final Map<String, ComponentModel> nameToComponentModel = CollectionFactory.newConcurrentMap();
 
@@ -58,21 +59,20 @@ public class ComponentClassTransformerIm
 
     private final ComponentClassCache componentClassCache;
 
-    private final String[] SUBPACKAGES = {"." + InternalConstants.PAGES_SUBPACKAGE + ".",
-            "." + InternalConstants.COMPONENTS_SUBPACKAGE + ".",
-            "." + InternalConstants.MIXINS_SUBPACKAGE + ".",
-            "." + InternalConstants.BASE_SUBPACKAGE + "."};
+    private final String[] SUBPACKAGES =
+    { "." + InternalConstants.PAGES_SUBPACKAGE + ".", "." + InternalConstants.COMPONENTS_SUBPACKAGE + ".",
+            "." + InternalConstants.MIXINS_SUBPACKAGE + ".", "." + InternalConstants.BASE_SUBPACKAGE + "." };
 
     /**
-     * @param workerChain         the ordered list of class transform works as a chain of command instance
+     * @param workerChain
+     *            the ordered list of class transform works as a chain of command instance
      * @param classSource
      * @param componentClassCache
      */
-    public ComponentClassTransformerImpl(ComponentClassTransformWorker workerChain,
-                                         LoggerSource loggerSource,
-                                         @ComponentLayer ClassFactory classFactory,
-                                         @ComponentLayer CtClassSource classSource,
-                                         ComponentClassCache componentClassCache)
+    public ComponentClassTransformerImpl(ComponentClassTransformWorker workerChain, LoggerSource loggerSource,
+            @ComponentLayer
+            ClassFactory classFactory, @ComponentLayer
+            CtClassSource classSource, ComponentClassCache componentClassCache)
     {
         this.workerChain = workerChain;
         this.loggerSource = loggerSource;
@@ -96,7 +96,8 @@ public class ComponentClassTransformerIm
 
         // Component classes must be public
 
-        if (!Modifier.isPublic(ctClass.getModifiers())) return;
+        if (!Modifier.isPublic(ctClass.getModifiers()))
+            return;
 
         try
         {
@@ -104,7 +105,8 @@ public class ComponentClassTransformerIm
 
             CtConstructor ctor = ctClass.getConstructor("()V");
 
-            if (!Modifier.isPublic(ctor.getModifiers())) return;
+            if (!Modifier.isPublic(ctor.getModifiers()))
+                return;
         }
         catch (NotFoundException ex)
         {
@@ -115,8 +117,8 @@ public class ComponentClassTransformerIm
         // Inner classes are loaded by the same class loader as the component, but are
         // not components and are not transformed.
 
-
-        if (ctClass.getName().contains("$")) return;
+        if (ctClass.getName().contains("$"))
+            return;
 
         // Force the creation of the parent class.
 
@@ -137,18 +139,18 @@ public class ComponentClassTransformerIm
         // If the parent class is in a controlled package, it will already have been loaded and
         // transformed (that is driven by the ComponentInstantiatorSource).
 
-        InternalClassTransformation parentTransformation = nameToClassTransformation
-                .get(parentClassname);
+        InternalClassTransformation parentTransformation = nameToClassTransformation.get(parentClassname);
 
         // TAPESTRY-2449: Ignore the base class that Groovy can inject
 
-        if (parentTransformation == null && !(parentClassname.equals("java.lang.Object") || parentClassname.equals(
-                "groovy.lang.GroovyObjectSupport")))
+        if (parentTransformation == null
+                && !(parentClassname.equals("java.lang.Object") || parentClassname
+                        .equals("groovy.lang.GroovyObjectSupport")))
         {
             String suggestedPackageName = buildSuggestedPackageName(classname);
 
-            throw new RuntimeException(
-                    ServicesMessages.baseClassInWrongPackage(parentClassname, classname, suggestedPackageName));
+            throw new RuntimeException(ServicesMessages.baseClassInWrongPackage(parentClassname, classname,
+                    suggestedPackageName));
         }
 
         // TODO: Check that the name is not already in the map. But I think that can't happen,
@@ -160,16 +162,17 @@ public class ComponentClassTransformerIm
 
         MutableComponentModel model = new MutableComponentModelImpl(classname, logger, baseResource, parentModel);
 
-        InternalClassTransformation transformation =
-                parentTransformation == null
-                ? new InternalClassTransformationImpl(classFactory, ctClass, componentClassCache, model, classSource)
+        InternalClassTransformation transformation = parentTransformation == null ? new InternalClassTransformationImpl(
+                classFactory, ctClass, componentClassCache, model, classSource)
                 : parentTransformation.createChildTransformation(ctClass, model);
 
+        String transformerDescription = null;
+
         try
         {
             workerChain.transform(transformation, model);
 
-            transformation.finish();
+            transformerDescription = transformation.finish();
         }
         catch (Throwable ex)
         {
@@ -177,7 +180,7 @@ public class ComponentClassTransformerIm
         }
 
         transformLogger.debug(TapestryMarkers.CLASS_TRANSFORMATION, "Finished class transformation: {}",
-                              transformation);
+                transformerDescription);
 
         nameToClassTransformation.put(classname, transformation);
         nameToComponentModel.put(classname, model);
@@ -187,7 +190,8 @@ public class ComponentClassTransformerIm
     {
         InternalClassTransformation ct = nameToClassTransformation.get(componentClassName);
 
-        if (ct == null) throw new RuntimeException(ServicesMessages.classNotTransformed(componentClassName));
+        if (ct == null)
+            throw new RuntimeException(ServicesMessages.classNotTransformed(componentClassName));
 
         try
         {
@@ -207,10 +211,11 @@ public class ComponentClassTransformerIm
 
             // Keep the leading '.' in the subpackage name and tack on "base".
 
-            if (pos > 0) return className.substring(0, pos + 1) + InternalConstants.BASE_SUBPACKAGE;
+            if (pos > 0)
+                return className.substring(0, pos + 1) + InternalConstants.BASE_SUBPACKAGE;
         }
 
-        // Is this even reachable?  className should always be in a controlled package and so
+        // Is this even reachable? className should always be in a controlled package and so
         // some subpackage above should have matched.
 
         return null;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java?rev=936231&r1=936230&r2=936231&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java Wed Apr 21 09:45:20 2010
@@ -42,8 +42,10 @@ public interface InternalClassTransforma
      * Invoked after all {@link ComponentClassTransformWorker}s have had their chance to work over the class. This
      * performs any final operations for the class transformation, which includes coming up with the final constructor
      * method for the class.
+     * 
+     * @return the description of the transformation, so that it can be logged (quite verbose)
      */
-    void finish();
+    String finish();
 
     /**
      * Called (after {@link #finish()}) to construct an instantiator for the component.

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=936231&r1=936230&r2=936231&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 Apr 21 09:45:20 2010
@@ -720,7 +720,7 @@ public final class InternalClassTransfor
 
     private final String resourcesFieldName;
 
-    private final StringBuilder description = new StringBuilder(INIT_BUFFER_SIZE);
+    private StringBuilder description = new StringBuilder(INIT_BUFFER_SIZE);
 
     private Formatter formatter = new Formatter(description);
 
@@ -832,6 +832,7 @@ public final class InternalClassTransfor
         classAnnotations = null;
         constructor = null;
         formatter = null;
+        description = null;
     }
 
     public String getResourcesFieldName()
@@ -1791,7 +1792,7 @@ public final class InternalClassTransfor
         return classPool.get(type);
     }
 
-    public void finish()
+    public String finish()
     {
         failIfFrozen();
 
@@ -1811,7 +1812,11 @@ public final class InternalClassTransfor
 
         addConstructor(initializer);
 
+        String description = toString();
+
         freeze();
+
+        return description;
     }
 
     private void addConstructor(String initializer)
@@ -2019,7 +2024,8 @@ public final class InternalClassTransfor
                 builder.append(interfaces[i].getName());
             }
 
-            formatter.format("\n\n%s", description.toString());
+            if (description != null)
+                formatter.format("\n\n%s", description.toString());
         }
         catch (NotFoundException ex)
         {