]
Richard Kennard commented on JBWEB-200:
---------------------------------------
Okay terrific. Thanks so much for your quick response!
Just while you're there though, do you want to check whether
JasperLoader.loadClass(name, resolve) should be synchronized? This bug may come up again
somewhere else?
Richard.
REGRESSION: JSP generation uses TomcatInjectionContainer unsafely,
leading to race condition
--------------------------------------------------------------------------------------------
Key: JBWEB-200
URL:
https://issues.jboss.org/browse/JBWEB-200
Project: JBoss Web
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: Tomcat
Affects Versions: JBossWeb-3.0.0.CR1
Environment: JBoss AS 6.0.0.Final (apologies if this isn't
JBossWeb-3.0.0.CR1?)
Reporter: Richard Kennard
Assignee: Remy Maucherat
Priority: Critical
Hi guys,
Thanks for the great work you do on JBoss Web! We've been using it in production for
years and it's a really solid product.
We are just upgrading from JBoss 5.1.0.GA to JBoss AS 6.0.0.Final. There appears to have
been a serious regression in the JSP compilation. In JBoss 5.1.0.GA our JSP page compiled
to this (looking in the /work folder)...
PageContext pageContext = _jspx_page_context;
JspWriter out = _jspx_page_context.getOut();
// tags:page-loggedIn
org.apache.jsp.tag.web.page_002dloggedIn_tag
_jspx_th_tags_005fpage_002dloggedIn_005f0 = (new
org.apache.jsp.tag.web.page_002dloggedIn_tag());
_jsp_instancemanager.newInstance(_jspx_th_tags_005fpage_002dloggedIn_005f0);
_jspx_th_tags_005fpage_002dloggedIn_005f0.setJspContext(_jspx_page_context);
...but in JBoss AS 6.0.0.Final it compiles to this...
PageContext pageContext = _jspx_page_context;
JspWriter out = _jspx_page_context.getOut();
// tags:page-loggedIn
org.apache.jsp.tag.web.page_002dloggedIn_tag
_jspx_th_tags_005fpage_002dloggedIn_005f0 =
(org.apache.jsp.tag.web.page_002dloggedIn_tag)_jsp_instancemanager.newInstance("org.apache.jsp.tag.web.page_002dloggedIn_tag",
this.getClass().getClassLoader());
_jspx_th_tags_005fpage_002dloggedIn_005f0.setJspContext(_jspx_page_context);
There is a slight difference in which _jsp_instancemanager method is being called. The
new JSP is calling the version of the method which takes a name. The old JSP was using the
version which takes an Object.
Behind the scenes _jsp_instance maps to TomcatInjectionContainer, which uses a
ClassLoader implemented by JasperLoader. However, JasperLoader.loadClass(name, resolve)
*is not Thread safe*. Even though it probably should be
(java.lang.ClassLoader.loadClass(name, resolve) *is* Thread-safe, but JasperLoader
overrides it and neglects to use 'synchronized' - so there may be 2 bugs here?)
Anyway, regardless of whether the bug is in the JSP compilation or JasperLoader, under
concurrent load we see this:
Caused by: java.lang.IllegalArgumentException: org.apache.jsp.tag.web
at java.lang.ClassLoader.definePackage(ClassLoader.java:1452)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:135)
at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:67)
at
org.jboss.web.tomcat.service.TomcatInjectionContainer.newInstance(TomcatInjectionContainer.java:278)
at
org.apache.jsp.platforms.platforms_jsp._jspx_meth_tags_005fpage_002dloggedIn_005f0(platforms_jsp.java:113)
Which is caused by this:
2011-05-23 13:53:11,874 ERROR
[org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/].[jsp]]
(http-116.50.21.248-8443-7) Servlet.service() for servlet jsp threw exception:
java.lang.LinkageError: loader (instance of org/apache/jasper/servlet/JasperLoader):
attempted duplicate class definition for name:
"org/apache/jsp/tag/web/page_002dloggedIn_tag"
at java.lang.ClassLoader.defineClass1(Native Method) [:1.6.0_24]
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) [:1.6.0_24]
at java.lang.ClassLoader.defineClass(ClassLoader.java:616) [:1.6.0_24]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
[:1.6.0_24]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283) [:1.6.0_24]
at java.net.URLClassLoader.access$000(URLClassLoader.java:58) [:1.6.0_24]
at java.net.URLClassLoader$1.run(URLClassLoader.java:197) [:1.6.0_24]
at java.security.AccessController.doPrivileged(Native Method) [:1.6.0_24]
at java.net.URLClassLoader.findClass(URLClassLoader.java:190) [:1.6.0_24]
at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:135)
[:6.0.0.Final]
at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:67)
[:6.0.0.Final]
at
org.jboss.web.tomcat.service.TomcatInjectionContainer.newInstance(TomcatInjectionContainer.java:278)
[:6.0.0.Final]
It would appear two instances of the platforms.jsp page, executed concurrently, both try
to create the missing 'page-loggedIn.tag' at the same time. This is a regression
from JBoss AS 5.1.0 which could handle building JSPs concurrently (and under load) without
problem. Note we are using a shared JSP tagfile (in /WEB-INF/tags).
--
This message is automatically generated by JIRA.
For more information on JIRA, see: