[jboss-jira] [JBoss JIRA] Updated: (JBWEB-200) REGRESSION: JSP generation uses TomcatInjectionContainer unsafely, leading to race condition

Richard Kennard (JIRA) jira-events at lists.jboss.org
Mon May 23 00:56:00 EDT 2011


     [ https://issues.jboss.org/browse/JBWEB-200?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Richard Kennard updated JBWEB-200:
----------------------------------

    Description: 
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]

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 here (in /WEB-INF/tags).

  was:
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]

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 here (in /WEB-INF/tags).



> 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
>            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]
> 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 here (in /WEB-INF/tags).

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the jboss-jira mailing list