Simon, On 3/18/24 15:17, Simon Niederberger wrote:
I'm analyzing a memory leak reported by Tomcat, and have narrowed it down to org.apache.jasper.compiler.EncodingDetector:private static final XMLInputFactory XML_INPUT_FACTORY; static { XML_INPUT_FACTORY = XMLInputFactory.newInstance(); } This class is called by webapp code on a GET request at org.apache.jasper.compiler.EncodingDetector.<clinit>(EncodingDetector.java:38) at org.apache.jasper.compiler.ParserController.determineSyntaxAndEncoding(ParserController.java:324) at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:201) at org.apache.jasper.compiler.ParserController.parseDirectives(ParserController.java:128) at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:207) ... at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:396) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:380) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:328) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) The EncodingDetector class, if not yet loaded, will be loaded in the common classloader, then continue by loading the XMLInputFactory using the webapp context, and might end up with a XMLInputFactory implementation from a webapp-provided JAR. If that happens, the webapp can't undeploy. (In my case, woodstox WstxInputFactory registers itself as ServiceProvider for XMLInputFactory) For completeness: javax.xml.stream.FactoryFinder.findServiceProvider() is called without classloader (cl = null), and has if (cl == null) { //the current thread's context class loader serviceLoader = ServiceLoader.load(type); } else { serviceLoader = ServiceLoader.load(type, cl); } I can't find anything online about memory leaks from webapp-provided XMLInputFactory implementations, but this must be fairly common. Is my understanding correct, or have I mis-configured something? (I'm mainly wondering whether any XMLInputFactory-implementing JARs belong in tomcat/lib, but again I'm not finding anything online confirming that) Tomcat 10.1.19 JVM 17.0.10+7-Ubuntu-120.04.1 Ubuntu 20.04.6 LTS
I'm not sure how many web applications ship with an XMLInputSource, but they definitely do exist. I'm fairly sure most applications won't set a system property or ship with a stax.properties/jaxp.properties file to override the default implementation, but of course if it's possible, someone will eventually do it.
I'm curious: in your example, how are you declaring your implementation class, and which implementation are you using?
Are you able to log in EncodingDetector.<clinit> what the value of the thread's context classloader is? I would expect that it's using the common classloader, as you say, and that the implementation class would also be loaded using that same classloader.
-chris --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
