Hi Michael,

 

With the fear of having sent you on a pointless digging mission, I continued to modify my code (as well as read through SpringSource stuff) to make sure that I wasn’t doing something stupid and that Spring wasn’t doing something without me knowing. I further discovered that I’m not getting 2 errors per transform, rather there is one error for each transform that occurs. In the process I was discussing earlier, there was an intermediate transform occurring (xforms XML to XML) and then a secondary one (XML to HTML) that was occurring from the Spring XsltView. When I removed the intermediate transform, I only received 1 error per “request”.

 

Then, to make sure it wasn’t something specific on that transform, I tested using another method (with a totally different [simple] XSL) that does not rely on any underlying Spring view technology. In other words, a request arrives, an XSL gets executed which creates some JSON, and that is returned directly. In this case, there is one and only one transform occurring. This function is used by a browser tree navigator, so each time the user expands a branch in the tree, this method is called (in other words, it’s a dynamically populated tree control).

 

After a clean start and expanding 3 nodes, then “reload tomcat”, I get four messages (1 for the “root”, and 1 for each of the 3 branches I expanded). So in this case, the code being executed is very minimal (I’ve attached it again below). It’s worth noting that although the key (java.lang.ThreadLocal) is the same for all errors (4b934b93), the value is different. If 1000 transforms occurred (and is very likely), it would have one for each, which seems wrong given that once a transform completes, anything associated with it should get cleaned up too. So, by changing to the LRU model, that would just mean that I would have 8 leaks rather than 1000, but still, my gut tells me there shouldn’t be any.

 

Here’s the code that’s running (I switched back to JAXP just for testing):

 

private Templates cachedXSLT;

private DOMSource emptyDoc;

 

@PostConstruct

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

dbf.setNamespaceAware(true);

emptyDoc = new DOMSource(dbf.newDocumentBuilder().newDocument());

 

TransformerFactory transFact = TransformerFactory.newInstance();

ClassPathResource xslt = new ClassPathResource("treeNode.xsl");

StreamSource xsltSrc = new StreamSource(xslt.getInputStream());

cachedXSLT = transFact.newTemplates(xsltSrc);

 

Method:

StringWriter sw = new StringWriter();

StreamResult strmResult = new StreamResult(sw);

List<TreeNode> nodes = null;

try {

       Transformer trans = cachedXSLT.newTransformer();

       trans.setURIResolver(uriResolver);

       trans.setParameter("nodeId",nodeId);

       trans.transform(emptyDoc, strmResult);

nodes = mapper.readValue(sw.toString(),List.class);

} catch (Exception e) …

 

return (nodes);

 

Errors after 4 xforms:

 

SEVERE: The web application [/digitalguides] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@4b934b93]) and a value of type [net.sf.saxon.expr.sort.IntHashMap] (value [net.sf.saxon.expr.sort.IntHashMap@25b925b9]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

Feb 3, 2012 2:40:32 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks

SEVERE: The web application [/digitalguides] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@4b934b93]) and a value of type [net.sf.saxon.expr.sort.IntHashMap] (value [net.sf.saxon.expr.sort.IntHashMap@52cf52cf]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

Feb 3, 2012 2:40:32 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks

SEVERE: The web application [/digitalguides] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@4b934b93]) and a value of type [net.sf.saxon.expr.sort.IntHashMap] (value [net.sf.saxon.expr.sort.IntHashMap@6a696a69]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

Feb 3, 2012 2:40:32 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks

SEVERE: The web application [/digitalguides] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@4b934b93]) and a value of type [net.sf.saxon.expr.sort.IntHashMap] (value [net.sf.saxon.expr.sort.IntHashMap@53c753c7]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.