Uploaded image for project: 'JBoss Enterprise Application Platform'
  1. JBoss Enterprise Application Platform
  2. JBEAP-13945

[GSS](7.2.0) NullPointerException happens at ELEvaluator.parseExpressionString() due to a concurrency issue

    XMLWordPrintable

Details

    • Bug
    • Resolution: Obsolete
    • Major
    • None
    • 7.0.8.GA
    • EE
    • None
    • Hide

      1. Download and extract the attached example.zip
      2. Build and deploy example.war to EAP 7

      mvn clean package
      

      3. Access two JSPs (index.jsp and index2.jsp) to triger jsp compile almost at the same time. For example:

      curl http://localhost:8080/example/index.jsp & curl http://localhost:8080/example/index2.jsp &
      

      Then, you will see the following NPE high probability. Of cource, this is a timing issue, so you may not be able to reproduce the issue.

      You can use a byteman rule to reproduce the issue more reliabily. The byteman rule just invokes Thread.sleep once in 2 times.

      Show
      1. Download and extract the attached example.zip 2. Build and deploy example.war to EAP 7 mvn clean package 3. Access two JSPs (index.jsp and index2.jsp) to triger jsp compile almost at the same time. For example: curl http: //localhost:8080/example/index.jsp & curl http://localhost:8080/example/index2.jsp & Then, you will see the following NPE high probability. Of cource, this is a timing issue, so you may not be able to reproduce the issue. You can use a byteman rule to reproduce the issue more reliabily. The byteman rule just invokes Thread.sleep once in 2 times.

    Description

      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.)

      ERROR [io.undertow.request] (default task-4) UT005023: Exception handling request to /example/index.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
      
      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     }
      
      ~~~
       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) {
      

      Attachments

        Issue Links

          Activity

            People

              thofman Tomas Hofman
              rhn-support-mmiura Masafumi Miura
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: