[
https://issues.apache.org/jira/browse/VELOCITY-715?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Atsushi Isobe updated VELOCITY-715:
-----------------------------------
Attachment: FileResourceLoader.patch
FileResourceLoaderLeakedObjectTest.java
> 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
> Attachments: FileResourceLoader.patch,
> FileResourceLoaderLeakedObjectTest.java
>
>
> 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]