3

I'm using tomcat 8.0.9 (servlet 3.1, jsp 2.3, el 3.0) and trying to access a static property from a jsp page like so:

${Boolean.TRUE}

There is no error, but no output appears in the rendered result. What am I doing wrong?

EDIT

The answer to this question (marked as duplicate question) claims that since EL 3.0 (JSR-341, part of Java EE 7), it is possible to reference constants for all java.lang.* classes as they are implicitly imported and available like so

${Boolean.TRUE} 

This answer is NOT working for me, at least not with tomcat 8.

EDIT 2

From Oracle's JEE7 Tutorial (9.3.1.2 Referencing Object Properties or Collection Elements)

You can reference a static field or method using the syntax classname.field, as in the following example:

Boolean.FALSE

The classname is the name of the class without the package name. By default, all the java.lang packages are imported. You can import other packages, classes, and static fields as needed.
Community
  • 1
  • 1
Brice Roncace
  • 10,110
  • 9
  • 60
  • 69
  • I have the most basic of web applications with only an index.jsp page containing ` Should see true: ${Boolean.TRUE}` But the rendered html is blank after the colon. – Brice Roncace Jul 19 '14 at 20:39
  • Why not simply use a JSP scriptlet instead? <%= Boolean.TRUE %> – Vladimír Schäfer Jul 21 '14 at 21:36
  • 1
    As a general best practice we have scriptlet code disallowed on our apps. See http://stackoverflow.com/a/3180202/225217 – Brice Roncace Jul 21 '14 at 21:46
  • Are you sure you are on JEE7? As it behaves as in 6. Maybe you are packaging with application some old jars with EL implementation. – Gas Jul 21 '14 at 23:55
  • I'm on tomcat 8.0.9 (see http://tomcat.apache.org/whichversion.html) Tomcat's using jasper-el.jar and an el-api.jar that latter containing a manifest that reads `Name: javax/el/ Specification-Title: Expression Language Specification-Version: 3.0 Specification-Vendor: Sun Microsystems, Inc. Implementation-Title: javax.el Implementation-Version: 3.0.FR Implementation-Vendor: Apache Software Foundation` – Brice Roncace Jul 22 '14 at 14:33
  • I could see where Boolean.TRUE would be a unique case that may/may not work. Out of curiosity, try this: ${Boolean.TRUE == Boolean.TRUE} – alfreema Jul 23 '14 at 03:54
  • Yes, that does render "true" however so does `${Boolean.GARBAGE == Boolean.GARBAGE}`. The other test I've got in place is trying to get today's date via: `${java.time.LocalDate.now()}`, this is not rendering any output (I'm on jdk 8). – Brice Roncace Jul 23 '14 at 14:28

1 Answers1

7

UPDATE:

There is a bug in Tomcat's (at least as of 8.0.9) jsp-api.jar. According to the change log, it is fixed in Tomcat version 8.0.15.

As a workaround, in the apache-tomcat-8.0.9\lib folder replace jsp-api.jar with javax.servlet.jsp-api-2.3.2-b01.jar. Refresh the project in eclipse and you will see the output for

     Testing: ${Boolean.TRUE}

as:

    Testing: true

This was identified as a bug in GLASSFISH as well here.

In order to access static fields or methods outside of the java.lang package, those specific packages or classes must be added to the EL context (also discussed by BalusC here).

Here's an example allowing static access to classes in the java.time package for all jsp files in your web application:

@WebListener
public class Config implements ServletContextListener {
  @Override
  public void contextInitialized(ServletContextEvent event) {
    JspFactory.getDefaultFactory().getJspApplicationContext(event.getServletContext()).addELContextListener((ELContextEvent e) -> {
      e.getELContext().getImportHandler().importPackage("java.time");
    });
  }

  @Override
  public void contextDestroyed(ServletContextEvent event) {}
}

And now from the jsp, to return the current LocalDate, for example:

${LocalDate.now()}

Note that ${java.time.LocalDate.now()} does not work.

Community
  • 1
  • 1
Prasad
  • 3,785
  • 2
  • 14
  • 23
  • I tried what you recommended (using 8.0.3 does that matter) and I get a `Provider com.sun.el.ExpressionFactoryImpl not found` – buzzsawddog Jul 23 '14 at 13:45
  • Same result here as buzzsawddog. I tried using glassfish's latest el-api jar (http://mvnrepository.com/artifact/org.glassfish/javax.el/3.0.1-b05) and the behavior reverted back to what I saw using Tomcat 8's stock el-api.jar. Do I need to update the el-impl jar replace as well? – Brice Roncace Jul 23 '14 at 14:24
  • @buzzsawddog see my updated answer. Keep the el-api jars as is and change the jsp-api to javax.servlet.jsp-api-2.3.2-b01. – Prasad Jul 23 '14 at 16:19
  • @Prasad we're getting closer! `${Boolean.TRUE}` works, however, non-java.lang packaged classes like: `${java.time.LocalDate.now()}`, `${java.util.Calendar.getInstance()}`, and `${java.math.BigDecimal.ZERO}` do not. These render no output. Shouldn't this work too? – Brice Roncace Jul 23 '14 at 19:30
  • Excerpt from the JEE7 tutorial quoted in the question: `You can import other packages, classes, and static fields as needed.` – Brice Roncace Jul 23 '14 at 19:50
  • @Brice BalusC rightly pointed out. java.lang package is implicitly available in el. If you need to use classes from other packages you need to import by using [https://java.net/projects/el-spec/pages/StaticField] importHandler – Prasad Jul 23 '14 at 19:57
  • Ok, thanks. Yes, I see how BalusC outlined (http://stackoverflow.com/a/3735006/225217) how to make these classes available to the jsp. Is there a way to import a package or class into the ELContext on a per jsp basis rather than globally via a web listener during context initialization? – Brice Roncace Jul 23 '14 at 20:38
  • @Prasad Thanks for taking the time to answer. – Brice Roncace Jul 23 '14 at 21:02
  • Cannot make ${Boolean.TRUE} to work in WildFly 8.2.1. If I replace the jar, "wrong number of arguments" is thrown somewhere within JSP/EL code. – Alex Feb 13 '15 at 09:45