Search code examples
javaperformancejspeltomcat8

Is it possible to disable support for referencing static fields and methods for JSP 2.3 in Tomcat 8


Is it possible to turn off the support for referencing static fields and methods in Tomcat 8 which was added as part of Unified Expression Language 3.0.

We have ~4K JSP's in our application, with many ${undefined} (no scope specified) expressions, the migration to Tomcat 8 lead to significant performance degradation since the evaluation of those expression is legal 'null' value. We no longer use JSP technology for newer pages but the legacy one won't go away soon.

The problematic code is in javax.servlet.el.ScopedAttributeELResolver class, which tries to resolve the expression from ImportHandler that makes many Class.forName lookups, which fails largely due to the ClassNotFoundException.

@Override
public Object getValue(ELContext context, Object base, Object property) {
    if (context == null) {
        throw new NullPointerException();
    }

    Object result = null;

    if (base == null) {
        context.setPropertyResolved(base, property);
        if (property != null) {
            String key = property.toString();
            PageContext page = (PageContext) context
                    .getContext(JspContext.class);
            result = page.findAttribute(key);

            if (result == null) {
                // This might be the name of an imported class
                ImportHandler importHandler = context.getImportHandler();
                if (importHandler != null) {
                    Class<?> clazz = importHandler.resolveClass(key);
                    if (clazz != null) {
                        result = new ELClass(clazz);
                    }
                    if (result == null) {
                        // This might be the name of an imported static field
                        clazz = importHandler.resolveStatic(key);
                        if (clazz != null) {
                            try {
                                result = clazz.getField(key).get(null);
                            } catch (IllegalArgumentException | IllegalAccessException |
                                    NoSuchFieldException | SecurityException e) {
                                // Most (all?) of these should have been
                                // prevented by the checks when the import
                                // was defined.
                            }
                        }
                    }
                }
            }
        }
    }

    return result;
}

Update

A bug were opened for Tomcat 8 - performance problems when using scopeless optional attributes, which is closed as won't fixed. I thought that they may to add some property to disable the performance consuming code, but for now they won't, due to:

  • It would be Tomcat specific
  • It would have to be a system property since this is a spec class
  • It could not be applied per application - it would impact all applications running on that instance

Please Advise Thanks


Solution

  • It seems that Tomcat 8.0.33 resolved this problem with performance improvement by 10 times faster https://bz.apache.org/bugzilla/show_bug.cgi?id=57583