Bug 43632

Summary: NullPointerException in x:transform
Product: Taglibs Reporter: Rob Adamson <bobacus>
Component: Standard TaglibAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED WONTFIX    
Severity: normal CC: nicolas.flinois
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Hardware: Sun   
OS: SunOS   

Description Rob Adamson 2007-10-16 02:45:58 UTC
I may have discovered a bug in jakarta-taglibs-standard-1.1.2.

The JSP code

<x:transform doc="${onlineevents_archiveDoc}"
xslt="${onlineevents_archiveXSLT}">
<x:param name="order" value="${order}" />
</x:transform>

is very occasionally causing a NullPointerException, with the
following stack trace:

java.lang.NullPointerException
***
org.apache.taglibs.standard.tag.common.xml.TransformSupport.addParameter(TransformSupport.java:221)
***
org.apache.taglibs.standard.tag.common.xml.ParamSupport.doEndTag(ParamSupport.java:74)
***
org.apache.jsp.onlineevents.archive.default_jsp._jspx_meth_x_param_0(default_jsp.java:546)
***
org.apache.jsp.onlineevents.archive.default_jsp._jspx_meth_x_transform_0(default_jsp.java:515)
***
org.apache.jsp.onlineevents.archive.default_jsp._jspService(default_jsp.java:206)
*** org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
*** javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
*** org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
*** org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
*** org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
*** javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
***
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
***
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
***
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
***
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
*** org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
***
org.apache.catalina.cluster.tcp.ReplicationValve.invoke(ReplicationValve.java:346)
*** org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
***
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
*** org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
*** org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:425)
***
org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:452)
*** org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1285)
*** java.lang.Thread.run(Thread.java:595)

Looking at the source of TransformSupport, I see the offending method is:

   public void addParameter(String name, Object value) {
       t.setParameter(name, value);
   }

implying that instance variable 't' (of type
javax.xml.transform.Transformer) is set to null - which suggests some
kind of weird bug where it is either overwritten or not initialised
properly.

I'm a bit stuck as I can't reproduce this myself; it seems to be
occurring at random several times a day on my production site.

I had thought it was a concurrency issue and have tried wrapping the
call to <x:transform> in a synchronized block, just in case, but it
hasn't made any noticeable difference.

The server information is:
Tomcat 5.5.17
JVM: Sun 1.5.0_07-b03
OS: SunOS 5.9
Arch: sparc
Comment 1 Kris Schneider 2007-10-16 05:04:27 UTC
Make sure that ${order} does not evaluate to null. Transformer.setParameter
should throw an NPE if the parameter value is null.
Comment 2 Rob Adamson 2007-10-16 05:36:55 UTC
(In reply to comment #1)
> Make sure that ${order} does not evaluate to null. Transformer.setParameter
> should throw an NPE if the parameter value is null.

Yes, but the first entry in the stack trace is TransformSupport.addParameter, so
doesn't that imply that t is null?

Anyway I will add a check of ${order} to eliminate the possibility that it
evaluates to null.

Rob
Comment 3 Rob Adamson 2007-10-16 08:24:18 UTC
OK, the same NPE has occurred, and this time ${order} is definitely not null

<% if (pageContext.findAttribute("order")==null)
	throw new Exception("order==null"); 
%><x:transform doc="${onlineevents_archiveDoc}" xslt="${onlineevents_archiveXSLT}">
<x:param name="order" value="${order}" />
</x:transform>

Rob
Comment 4 Kris Schneider 2007-10-16 10:28:01 UTC
(In reply to comment #3)
Yeah, I skimmed too quickly. Actually, it looks like ParamSupport.doEndTag would
never allow it to be null anyway. I'm having a hard time seeing how the
Transformer in TransformSupport could be null though. It's set every time via
doStartTag and TransformFactory.newTransformer(Source) is supposed to guarantee
a non-null return value...
Comment 5 Henri Yandell 2007-10-16 22:59:54 UTC
Feels like a Sherlock Holmes mystery :)

Nothing unsets t, so either it's being set to null, or it's not being set in the
first place. The latter either because doStartTag is not being called, or
because doStartTag is not reaching the 't = ...' line. 

1) TransformerFactory breaking contract and returning null.
2) Container breaking contract and not calling doStartTag.
3) doStartTag throwing an Exception which is quietly caught. 

As nothing unsets t, I don't think concurrency would be at play, unless it's a
bug relating to (2) above. 

I can't see anything in the Tomcat release notes post 5.5.17 about doStartTag.

Only suggestion I have is to put tracing into the JSTL classes and try to hunt
down which it seems to be. 
Comment 6 Nicolas FLINOIS 2008-09-25 12:11:31 UTC
I faced exactly the same issue... then going to previous JSTL releases, and running the same x:transform, with the same XML & XSL files. The exception was different:

javax.xml.transform.TransformerConfigurationException: Impossible de compiler la feuille de style
	at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTemplates(Unknown Source)
	at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(Unknown Source)
....


The pb was the malformed XSL file... there was a BOM responsible for bad SAX parsing, after a file edition. What I am sure is 't' can be null if SAX failed to parse the XSL file (don't know if it is the same behavior with bad XML doc parsing), because when I updated my jstl.jar and standard.jar to last 1.1 release afterwards, the previous exception 

java.lang.NullPointerException
org.apache.taglibs.standard.tag.common.xml.TransformSupport.addParameter(TransformSupport.java:221).

went back.


I hope it helps,


Nicolas
Comment 7 Henri Yandell 2009-11-29 19:53:55 UTC
Resolving as I can't see how the code could be NPE'ing there and we needed more info to get any further.