Struts contention on WebCtxLoader

Solution Unverified - Updated

Environment

  • JBoss Enterprise Application Platform (EAP)
  • Struts

Issue

  • We use struts and see heavy thread contention on a WebCtxLoader$ENCLoader, for example:
"ajp-10.207.30.181-8009-408" daemon prio=10 tid=0x00002aaabc048800 nid=0xd96 waiting for monitor entry [0x00000000732c8000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:291)
	- waiting to lock <0x000000070d46dee8> (a org.jboss.web.tomcat.service.WebCtxLoader$ENCLoader)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	at org.apache.struts.util.RequestUtils.applicationClass(RequestUtils.java:117)
	at org.apache.struts.util.RequestUtils.canReuseActionForm(RequestUtils.java:248)
	at org.apache.struts.util.RequestUtils.createActionForm(RequestUtils.java:183)
	at org.apache.struts.action.RequestProcessor.processActionForm(RequestProcessor.java:331)
	at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:202)
	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
	at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)

Resolution

  • Upgrade to a later struts version where this reuse test tactic is dropped.

Root Cause

  • The problem is in the struts code, not the classloader. It is clearly hoping to save on creating some state which is why it calls RequestUtils.canReuseActionForm(). Unfortunately, this is another "clever optimization" that clearly has not been thought through or tested. The test calls loadClass to associate a string name with an implementation class and ends up bottlenecking all the client threads at scale.
Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.