Uploaded image for project: 'JBoss Enterprise Application Platform 4 and 5'
  1. JBoss Enterprise Application Platform 4 and 5
  2. JBPAPP-7006

Unsafe use of HashMap in TomcatInjectionContainer can lead to Infinite Loop

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Obsolete
    • Icon: Major Major
    • TBD EAP 5
    • EAP 5.0.1
    • Web
    • None
    • Hide

      While I could not reproduce this, and get the same infinite loop behaviour, I can show that it is possible to get at least two threads to acess the getEncInjectionsForClass(Class<?> clazz, boolean isDynamic) method of the same TomcatInjectionContainer object. I did this by enabling development mode, and setting the 'modificationTestInterval' of the JspServlet in deployers/jbossweb.deployer/web.xml

      <init-param>
      <param-name>development</param-name>
      <param-value>true</param-value>
      </init-param>
      <init-param>
      <param-name>modificationTestInterval</param-name>
      <param-value>0</param-value>
      </init-param>

      I then created a rendezvous with Byteman, and accessed two different jsps, deployed to the same web application. The Byteman script halted by first thread, to the first jsp, at line 443, an access to the hashMap, will the second thread entered the same method, of the same object, and also accessed the hashmap. See my Byteman script, and associated output below:

      RULE TomcatInjectionContainer
      CLASS org.jboss.web.tomcat.service.TomcatInjectionContainer
      METHOD getEncInjectionsForClass(Class, boolean)
      AT LINE 443
      IF true
      DO
      traceln("** creating rendezvous for class: " + $1);
      createRendezvous("encInjectionsEntry", 2);
      traceln("** rendezvous created");
      rendezvous("encInjectionsEntry");
      traceln("** rendezvous executed: " + $0)
      ENDRULE

      16:45:46,639 INFO [STDOUT] retransforming org.jboss.web.tomcat.service.TomcatInjectionContainer
      16:45:46,646 INFO [STDOUT] org.jboss.byteman.agent.Transformer : possible trigger for rule TomcatInjectionContainer in class org.jboss.web.tomcat.service.TomcatInjectionContainer
      16:45:46,661 INFO [STDOUT] RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into org.jboss.web.tomcat.service.TomcatInjectionContainer.getEncInjectionsForClass(java.lang.Class,boolean) java.util.Map for rule TomcatInjectionContainer
      16:45:46,669 INFO [STDOUT] org.jboss.byteman.agent.Transformer : inserted trigger for TomcatInjectionContainer in class org.jboss.web.tomcat.service.TomcatInjectionContainer
      16:45:49,257 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:49,268 INFO [STDOUT] HelperManager.install for helper classorg.jboss.byteman.rule.helper.Helper
      16:45:49,269 INFO [STDOUT] calling activated() for helper classorg.jboss.byteman.rule.helper.Helper
      16:45:49,269 INFO [STDOUT] Default helper activated
      16:45:49,269 INFO [STDOUT] calling installed(TomcatInjectionContainer) for helper classorg.jboss.byteman.rule.helper.Helper
      16:45:49,269 INFO [STDOUT] Installed rule using default helper : TomcatInjectionContainer
      16:45:49,269 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:49,270 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.encInjections_jsp
      16:45:49,270 INFO [STDOUT] ** rendezvous created
      16:45:52,236 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,237 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,237 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.otherEncInjections_jsp
      16:45:52,238 INFO [STDOUT] ** rendezvous created
      16:45:52,238 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,238 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,238 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,238 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.encInjections_jsp
      16:45:52,239 INFO [STDOUT] ** rendezvous created
      16:45:52,239 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,239 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,239 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,239 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.otherEncInjections_jsp
      16:45:52,239 INFO [STDOUT] ** rendezvous created
      16:45:52,239 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,241 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,241 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,241 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.encInjections_jsp
      16:45:52,241 INFO [STDOUT] ** rendezvous created
      16:45:52,242 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,243 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,243 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,243 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.otherEncInjections_jsp
      16:45:52,244 INFO [STDOUT] ** rendezvous created
      16:45:52,244 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,245 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,245 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,245 INFO [STDOUT] ** creating rendezvous for class: class org.apache.taglibs.standard.tag.rt.core.IfTag
      16:45:52,245 INFO [STDOUT] ** rendezvous created
      16:45:52,246 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,247 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,247 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,247 INFO [STDOUT] ** creating rendezvous for class: class org.apache.taglibs.standard.tag.rt.core.IfTag
      16:45:52,247 INFO [STDOUT] ** rendezvous created
      16:45:52,247 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,247 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,247 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,247 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,247 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,247 INFO [STDOUT] ** creating rendezvous for class: class javax.servlet.jsp.jstl.core.ConditionalTagSupport
      16:45:52,247 INFO [STDOUT] ** rendezvous created
      16:45:52,247 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,247 INFO [STDOUT] ** creating rendezvous for class: class javax.servlet.jsp.jstl.core.ConditionalTagSupport
      16:45:52,247 INFO [STDOUT] ** rendezvous created
      16:45:52,248 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,248 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,248 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,248 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,248 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1
      16:45:52,248 INFO [STDOUT] ** creating rendezvous for class: class javax.servlet.jsp.tagext.TagSupport
      16:45:52,248 INFO [STDOUT] TomcatInjectionContainer execute
      16:45:52,248 INFO [STDOUT] ** rendezvous created
      16:45:52,248 INFO [STDOUT] ** creating rendezvous for class: class javax.servlet.jsp.tagext.TagSupport
      16:45:52,248 INFO [STDOUT] ** rendezvous created
      16:45:52,248 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
      16:45:52,248 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86

      Show
      While I could not reproduce this, and get the same infinite loop behaviour, I can show that it is possible to get at least two threads to acess the getEncInjectionsForClass(Class<?> clazz, boolean isDynamic) method of the same TomcatInjectionContainer object. I did this by enabling development mode, and setting the 'modificationTestInterval' of the JspServlet in deployers/jbossweb.deployer/web.xml <init-param> <param-name>development</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>modificationTestInterval</param-name> <param-value>0</param-value> </init-param> I then created a rendezvous with Byteman, and accessed two different jsps, deployed to the same web application. The Byteman script halted by first thread, to the first jsp, at line 443, an access to the hashMap, will the second thread entered the same method, of the same object, and also accessed the hashmap. See my Byteman script, and associated output below: RULE TomcatInjectionContainer CLASS org.jboss.web.tomcat.service.TomcatInjectionContainer METHOD getEncInjectionsForClass(Class, boolean) AT LINE 443 IF true DO traceln("** creating rendezvous for class: " + $1); createRendezvous("encInjectionsEntry", 2); traceln("** rendezvous created"); rendezvous("encInjectionsEntry"); traceln("** rendezvous executed: " + $0) ENDRULE 16:45:46,639 INFO [STDOUT] retransforming org.jboss.web.tomcat.service.TomcatInjectionContainer 16:45:46,646 INFO [STDOUT] org.jboss.byteman.agent.Transformer : possible trigger for rule TomcatInjectionContainer in class org.jboss.web.tomcat.service.TomcatInjectionContainer 16:45:46,661 INFO [STDOUT] RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into org.jboss.web.tomcat.service.TomcatInjectionContainer.getEncInjectionsForClass(java.lang.Class,boolean) java.util.Map for rule TomcatInjectionContainer 16:45:46,669 INFO [STDOUT] org.jboss.byteman.agent.Transformer : inserted trigger for TomcatInjectionContainer in class org.jboss.web.tomcat.service.TomcatInjectionContainer 16:45:49,257 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:49,268 INFO [STDOUT] HelperManager.install for helper classorg.jboss.byteman.rule.helper.Helper 16:45:49,269 INFO [STDOUT] calling activated() for helper classorg.jboss.byteman.rule.helper.Helper 16:45:49,269 INFO [STDOUT] Default helper activated 16:45:49,269 INFO [STDOUT] calling installed(TomcatInjectionContainer) for helper classorg.jboss.byteman.rule.helper.Helper 16:45:49,269 INFO [STDOUT] Installed rule using default helper : TomcatInjectionContainer 16:45:49,269 INFO [STDOUT] TomcatInjectionContainer execute 16:45:49,270 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.encInjections_jsp 16:45:49,270 INFO [STDOUT] ** rendezvous created 16:45:52,236 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,237 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,237 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.otherEncInjections_jsp 16:45:52,238 INFO [STDOUT] ** rendezvous created 16:45:52,238 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,238 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,238 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,238 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.encInjections_jsp 16:45:52,239 INFO [STDOUT] ** rendezvous created 16:45:52,239 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,239 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,239 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,239 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.otherEncInjections_jsp 16:45:52,239 INFO [STDOUT] ** rendezvous created 16:45:52,239 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,241 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,241 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,241 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.encInjections_jsp 16:45:52,241 INFO [STDOUT] ** rendezvous created 16:45:52,242 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,243 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,243 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,243 INFO [STDOUT] ** creating rendezvous for class: class org.apache.jsp.otherEncInjections_jsp 16:45:52,244 INFO [STDOUT] ** rendezvous created 16:45:52,244 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,245 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,245 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,245 INFO [STDOUT] ** creating rendezvous for class: class org.apache.taglibs.standard.tag.rt.core.IfTag 16:45:52,245 INFO [STDOUT] ** rendezvous created 16:45:52,246 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,247 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,247 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,247 INFO [STDOUT] ** creating rendezvous for class: class org.apache.taglibs.standard.tag.rt.core.IfTag 16:45:52,247 INFO [STDOUT] ** rendezvous created 16:45:52,247 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,247 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,247 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,247 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,247 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,247 INFO [STDOUT] ** creating rendezvous for class: class javax.servlet.jsp.jstl.core.ConditionalTagSupport 16:45:52,247 INFO [STDOUT] ** rendezvous created 16:45:52,247 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,247 INFO [STDOUT] ** creating rendezvous for class: class javax.servlet.jsp.jstl.core.ConditionalTagSupport 16:45:52,247 INFO [STDOUT] ** rendezvous created 16:45:52,248 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,248 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,248 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,248 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,248 INFO [STDOUT] Rule.execute called for TomcatInjectionContainer_1 16:45:52,248 INFO [STDOUT] ** creating rendezvous for class: class javax.servlet.jsp.tagext.TagSupport 16:45:52,248 INFO [STDOUT] TomcatInjectionContainer execute 16:45:52,248 INFO [STDOUT] ** rendezvous created 16:45:52,248 INFO [STDOUT] ** creating rendezvous for class: class javax.servlet.jsp.tagext.TagSupport 16:45:52,248 INFO [STDOUT] ** rendezvous created 16:45:52,248 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86 16:45:52,248 INFO [STDOUT] ** rendezvous executed: org.jboss.web.tomcat.service.TomcatInjectionContainer@21cb0e86
    • Hide

      Set the following JVM Properties on JBoss.

      -Dorg.apache.jasper.Constants.USE_INSTANCE_MANAGER_FOR_TAGS=false
      -Dorg.apache.jasper.Constants.INJECT_TAGS=false

      Unless some tag classes use injection, these should be set to false. The reason is that many tags are not poolable (simple tags, which most users now use), and as pages can easily use tens of them, going through the instance manager + injection has a very significant cost. Switching these to false, should prevent the TomcatInjectionContainer class from being used, and hence is a workaround for the problem.

      Show
      Set the following JVM Properties on JBoss. -Dorg.apache.jasper.Constants.USE_INSTANCE_MANAGER_FOR_TAGS=false -Dorg.apache.jasper.Constants.INJECT_TAGS=false Unless some tag classes use injection, these should be set to false. The reason is that many tags are not poolable (simple tags, which most users now use), and as pages can easily use tens of them, going through the instance manager + injection has a very significant cost. Switching these to false, should prevent the TomcatInjectionContainer class from being used, and hence is a workaround for the problem.
    • NEW

      JBoss experiences high cpu, with many threads blocked, waiting behind a threads running in an apparent infinite loop with stack traces like:

      at java.util.HashMap.get(HashMap.java:303)
      at org.jboss.web.tomcat.service.TomcatInjectionContainer.getEncInjectionsForClass(TomcatInjectionContainer.java:443)
      at org.jboss.web.tomcat.service.TomcatInjectionContainer.getEncInjectionsForObject(TomcatInjectionContainer.java:435)
      at org.jboss.web.tomcat.service.TomcatInjectionContainer.processInjectors(TomcatInjectionContainer.java:355)
      at org.jboss.web.tomcat.service.TomcatInjectionContainer.newInstance(TomcatInjectionContainer.java:271)
      at org.jboss.web.tomcat.service.TomcatInjectionContainer.newInstance(TomcatInjectionContainer.java:265)
      at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:145)

      • locked <0x00000007164e5370> (a org.apache.jasper.servlet.JspServletWrapper)
        at org.apache.jasper.servlet.JspServletWrapper.getDependants(JspServletWrapper.java:258)
        at org.apache.jasper.compiler.Compiler.isOutDated(Compiler.java:456)
        at org.apache.jasper.compiler.Compiler.isOutDated(Compiler.java:377)
        at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:581)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:312)
      • locked <0x00000007164e5370> (a org.apache.jasper.servlet.JspServletWrapper)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:322)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:249)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:638)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:543)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:480)
        at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968)
        at org.apache.jsp.crossSiteSharing.crosssiteinclude_jsp._jspx_meth_c_005fif_005f1(crosssiteinclude_jsp.java:305)
        at org.apache.jsp.crossSiteSharing.crosssiteinclude_jsp._jspx_meth_c_005fotherwise_005f0(crosssiteinclude_jsp.java:270)
        at org.apache.jsp.crossSiteSharing.crosssiteinclude_jsp._jspService(crosssiteinclude_jsp.java:205)

              rmaucher Remy Maucherat
              rhn-support-jshepher Jason Shepherd
              Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: