[ 
https://issues.apache.org/jira/browse/VELOCITY-715?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Atsushi Isobe updated VELOCITY-715:
-----------------------------------

    Remaining Estimate:     (was: 1h)
     Original Estimate:     (was: 1h)

> Leaked object in FileResourceLoader#templatePaths
> -------------------------------------------------
>
>                 Key: VELOCITY-715
>                 URL: https://issues.apache.org/jira/browse/VELOCITY-715
>             Project: Velocity
>          Issue Type: Bug
>          Components: Engine
>         Environment: Sun JRE 6 Update 13
>            Reporter: Atsushi Isobe
>            Priority: Minor
>
>  org.apache.velocity.runtime.resource.loader.FileResourceLoader#templatePaths 
> has stored templatename and real file path permanently.So if 
> VelocityEngine#getTemplate(String) has called by too many files, 
> #templatePaths have been enlarged. 
> Below my patch and test class.
> ---------------------------------------------------------------------------
> --- 
> ./src/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java
>     (revision 772904)
> +++ 
> ./src/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java
>     (working copy)
> @@ -30,6 +30,7 @@
>  import java.util.HashMap;
>  import java.util.List;
>  import java.util.Map;
> +import java.util.WeakHashMap;
>  
>  import org.apache.commons.collections.ExtendedProperties;
>  import org.apache.velocity.exception.ResourceNotFoundException;
> @@ -61,7 +62,7 @@
>       * times of the files. This is synchronizedMap
>       * instance.
>       */
> -    private Map templatePaths = Collections.synchronizedMap(new HashMap());
> +    private Map templatePaths = Collections.synchronizedMap(new 
> WeakHashMap());
>  
>      /** Shall we inspect unicode files to see what encoding they contain?. */
>      private boolean unicode = false;
> @@ -330,8 +331,8 @@
>                  currentFile = testFile;
>              }
>          }
> -        File file = getFile(path, fileName);
> -        if (currentFile == null || !file.exists())
> +        File file = path != null ? getFile(path, fileName) : null;
> +        if (currentFile == null || file == null || !file.exists())
>          {
>              /*
>               * noop: if the file is missing now (either the cached
> @@ -365,6 +366,10 @@
>      public long getLastModified(Resource resource)
>      {
>          String path = (String) templatePaths.get(resource.getName());
> +        if (path == null)
> +        {
> +             return 0;
> +        }
>          File file = getFile(path, resource.getName());
>  
>          if (file.canRead())
> ---------------------------------------------------------------------------
> import java.io.File;
> import java.io.IOException;
> import java.io.StringWriter;
> import java.text.DecimalFormat;
> import java.util.Properties;
> import org.apache.commons.io.FileUtils;
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> import org.apache.velocity.Template;
> import org.apache.velocity.VelocityContext;
> import org.apache.velocity.app.Velocity;
> import org.apache.velocity.app.VelocityEngine;
> import org.apache.velocity.exception.MethodInvocationException;
> import org.apache.velocity.exception.ParseErrorException;
> import org.apache.velocity.exception.ResourceNotFoundException;
> public class FileResourceLoaderLeakedObjectTest {
>       private static final String TEMPLATE_ENCODING = "UTF-8";
>       private static final File TEMPLATE_DIRECTORY = new File("./");
>       private static final String TEMPLATE_PREFIX = "testTemplate";
>       private static final String TEMPLATE_SUFFIX = ".vm";
>       private static final String TEMPLATE_STRING = "foobar";
>       private static final Log log = 
> LogFactory.getLog(FileResourceLoaderLeakedObjectTest.class);
>       public static void main(String[] args) throws Exception {
>               VelocityEngine ve = new VelocityEngine();
>               Properties properties = new Properties();
>         properties.put(Velocity.FILE_RESOURCE_LOADER_PATH, 
> TEMPLATE_DIRECTORY.getPath());
>               ve.init(properties);
>               VelocityContext context = new VelocityContext();
>               DecimalFormat countFormat = new DecimalFormat("000,000");
>               DecimalFormat totalFormat = new DecimalFormat("000,000,000");
>               
>               StringWriter writer = new StringWriter();
>               File tmp = null;
>               for (int i = 0; i < 0x100000; i++) {
>                       try {
>                               tmp = File.createTempFile(TEMPLATE_PREFIX, 
> TEMPLATE_SUFFIX, TEMPLATE_DIRECTORY);
>                               FileUtils.writeStringToFile(tmp, 
> TEMPLATE_STRING, TEMPLATE_ENCODING);
>                               Template template = 
> ve.getTemplate(tmp.getPath(), TEMPLATE_ENCODING);
>                               template.merge(context, writer);
>                               if ((i & 0xFFFF) == 0) {
>                                       System.gc();
>                                       Runtime runtime = Runtime.getRuntime();
>                                       log.info(new StringBuilder("count: 
> ").append(countFormat.format(i)).append(" total: 
> ").append(totalFormat.format(runtime.totalMemory() - runtime.freeMemory())));
>                               }
>                       } catch (ResourceNotFoundException e) {
>                               log.warn("", e);
>                       } catch (ParseErrorException e) {
>                               log.warn("", e);
>                       } catch (MethodInvocationException e) {
>                               log.warn("", e);
>                       } catch (IOException e) {
>                               log.warn("", e);
>                       } catch (Exception e) {
>                               log.warn("", e);
>                       } finally {
>                               if (tmp != null && tmp.exists()) {
>                                       tmp.delete();
>                               }
>                       }
>               }
>       }
> }
> ---------------------------------------------------------------------------

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to