[jboss-jira] [JBoss JIRA] (JBEE-184) NullPointerException happens at ELEvaluator.parseExpressionString() due to a concurrency issue

Masafumi Miura (JIRA) issues at jboss.org
Wed Dec 6 09:59:00 EST 2017


Masafumi Miura created JBEE-184:
-----------------------------------

             Summary: NullPointerException happens at ELEvaluator.parseExpressionString() due to a concurrency issue
                 Key: JBEE-184
                 URL: https://issues.jboss.org/browse/JBEE-184
             Project: JBoss JavaEE Spec APIs
          Issue Type: Bug
          Components: jboss-jstl-api
         Environment: - JBoss EAP 7.0.8
- jboss-jstl-api_1.2_spec-1.1.3.Final
            Reporter: Masafumi Miura
            Assignee: Scott Marlow
         Attachments: byteman-script.btm, example.zip

The following NullPointerException happens at ELEvaluator.parseExpressionString() due to a concurrency issue. 

Once this NPE happens, you will see same NPE every time when accessing the failed JSP. (If development="true" is configured in <jsp-config>, recompile can happen in the next access, so NPE can disappear after successful compilation in the next access.)

{code}
ERROR [io.undertow.request] (default task-4) UT005023: Exception handling request to /dsl/g/clsys/cl/nop-constind/CNC001.jsp: org.apache.jasper.JasperException: JBWEB004001: Unable to compile class for JSP
    at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:667) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:358) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:402) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:346) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [jboss-servlet-api_3.1_spec-1.0.0.Final-redhat-1.jar:1.0.0.Final-redhat-1]
    ...(snip)...
    ...
Caused by: java.lang.NullPointerException
    at org.apache.taglibs.standard.lang.jstl.ELEvaluator.parseExpressionString(ELEvaluator.java:276) [jboss-jstl-api_1.2_spec-1.1.3.Final-redhat-1.jar:1.1.3.Final-redhat-1]
    at org.apache.taglibs.standard.lang.jstl.Evaluator.validate(Evaluator.java:71) [jboss-jstl-api_1.2_spec-1.1.3.Final-redhat-1.jar:1.1.3.Final-redhat-1]
    at org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager.validate(ExpressionEvaluatorManager.java:131) [jboss-jstl-api_1.2_spec-1.1.3.Final-redhat-1.jar:1.1.3.Final-redhat-1]
    at org.apache.taglibs.standard.tlv.el.ValidationUtil.validateExpression(ValidationUtil.java:26) [jboss-jstl-api_1.2_spec-1.1.3.Final-redhat-1.jar:1.1.3.Final-redhat-1]
    at org.apache.taglibs.standard.tlv.el.JstlELCoreTLV.validateExpression(JstlELCoreTLV.java:26) [jboss-jstl-api_1.2_spec-1.1.3.Final-redhat-1.jar:1.1.3.Final-redhat-1]
    at org.apache.taglibs.standard.tlv.JstlCoreTLV$Handler.startElement(JstlCoreTLV.java:158) [jboss-jstl-api_1.2_spec-1.1.3.Final-redhat-1.jar:1.1.3.Final-redhat-1]
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:498)
    at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:180)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:275)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1653)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:324)
    at org.apache.xerces.parsers.XML11Configuration.parse(XML11Configuration.java:875)
    at org.apache.xerces.parsers.XML11Configuration.parse(XML11Configuration.java:798)
    at org.apache.xerces.parsers.XMLParser.parse(XMLParser.java:108)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1198)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:564)
    at org.apache.taglibs.standard.tlv.JstlBaseTLV.validate(JstlBaseTLV.java:158) [jboss-jstl-api_1.2_spec-1.1.3.Final-redhat-1.jar:1.1.3.Final-redhat-1]
    at org.apache.taglibs.standard.tlv.JstlCoreTLV.validate(JstlCoreTLV.java:97) [jboss-jstl-api_1.2_spec-1.1.3.Final-redhat-1.jar:1.1.3.Final-redhat-1]
    at org.apache.jasper.compiler.TagLibraryInfoImpl.validate(TagLibraryInfoImpl.java:552) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.compiler.Validator.validateXmlView(Validator.java:1856) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.compiler.Validator.validateExDirectives(Validator.java:1825) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:218) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.compiler.Compiler.compile(Compiler.java:354) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.compiler.Compiler.compile(Compiler.java:334) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.compiler.Compiler.compile(Compiler.java:321) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:652) [jastow-2.0.0.Final-redhat-1.jar:2.0.0.Final-redhat-1]
    ... 61 more
{code}



- https://github.com/jboss/jboss-jstl-api_spec/blob/jboss-jstl-api_1.2_spec-1.1.3.Final/src/main/java/org/apache/taglibs/standard/lang/jstl/ELEvaluator.java#L275-L277

{code}
252     public Object parseExpressionString(String pExpressionString)
253             throws ELException {
254         // See if it's an empty String
255         if (pExpressionString.length() == 0) {
256             return "";
257         }
258
259         if (!(mBypassCache) && (sCachedExpressionStrings == null)) {
260             createExpressionStringMap();
261         }
262
263         // See if it's in the cache
264         Object ret =
265                 mBypassCache ?
266                         null :
267                         sCachedExpressionStrings.get(pExpressionString);
268
269         if (ret == null) {
270             // Parse the expression
271             Reader r = new StringReader(pExpressionString);
272             ELParser parser = new ELParser(r);
273             try {
274                 ret = parser.ExpressionString();
275                 if (!mBypassCache) {
276                     sCachedExpressionStrings.put(pExpressionString, ret); // <- NPE occurred at here
277                 }
278             }
279             catch (ParseException exc) {
280                 throw new ELException
281                         (formatParseException(pExpressionString,
282                                 exc));
283             }
284             catch (TokenMgrError exc) {
285                 // Note - this should never be reached, since the parser is
286                 // constructed to tokenize any input (illegal inputs get
287                 // parsed to <BADLY_ESCAPED_STRING_LITERAL> or
288                 // <ILLEGAL_CHARACTER>
289                 throw new ELException(exc.getMessage());
290             }
291         }
292         return ret;
293     }
{code}

- https://github.com/jboss/jboss-jstl-api_spec/blob/jboss-jstl-api_1.2_spec-1.1.3.Final/src/main/java/org/apache/taglibs/standard/lang/jstl/Evaluator.java#L70-L71

{code}
~~~
 51     /**
 52      * The singleton instance of the evaluator *
 53      */
 54     static ELEvaluator sEvaluator =
 55             new ELEvaluator
 56                     (new JSTLVariableResolver());
 :
 62     /**
 63      * Translation time validation of an attribute value.  This method
 64      * will return a null String if the attribute value is valid;
 65      * otherwise an error message.
 66      */
 67     public String validate(String pAttributeName,
 68                            String pAttributeValue) {
 69         try {
 70             sEvaluator.setBypassCache(true);   // <-- mBypassCache is set to true before invoking parseExpressionString()
 71             sEvaluator.parseExpressionString(pAttributeValue);
 72             sEvaluator.setBypassCache(false);
 73             return null;
 74         }
 75         catch (ELException exc) {
{code}



--
This message was sent by Atlassian JIRA
(v7.5.0#75005)


More information about the jboss-jira mailing list