JSP at GlassFish
JSR 245 MR: Part I - Expression Language (EL)
This is a quick update on JSP and EL (Expression Language) specification.
Although the EL specification has been separated from the JSP specification, for various reasons, we have not taken the last step to create a new JSR for EL. The proposed work on the JSP MR and EL MR has been filed under JSR-245. The details can be obtained from here.
The close date for the MR is March 3, 2009. Please send comments to me.
This blog covers the EL MR.
One of the most requested feature enhancement to EL is the ability to invoke
methods in EL expressions. The MethodExpression in the current EL can be
used to specify a method in the EL expression. For instance, in the following
JSF code fragment,
<h:commandButton action="#{trader.buy}" value="buy"/>
the method buy in the bean trader is specified in EL. This method is
is not invoked here, but instead, it is passed to the tag handler, and
can only be invoked from Java codes. Also, the parameter types of the method cannot be
obtained from the EL expression, but must be specified in the TLD (Tag Library
Descriptor). At the method invocation, the actual arguments (also not
specified in the EL expression) are coerced to the corresponding parameter
types and passed to the method. As you can see, there are a lot things
that need to be done in Java code to make a method call.
The proposed EL MR allows for specifying the method arguments, as well as the invocation of the method in the EL expression itself. The required changes in EL syntax to do this is surprisingly little. All we need to do to is add (what else) a list of arguments in parenthesis to the method calls. For instance, we can added the argument "JAVA" to above JSF fragment:
<h:commandButton action="#{trader.buy('JAVA')}" value="buy"/>
One thing nice about this new syntax is that you can tell immediately that this is a method call, and that the method
takes one parameter of the type String. Furthermore, we also specify the actual argument
to pass to the method when invoked. There is no need to specify the parameter types in the TLD, and there is no hidden arguments in the method
call.
Note in the above code, the EL expression, being a deferred method expression, does not cause the method to be invoked. To actually invoke the method and retrieve the method return value, we can write in a JSP page:
The stock price bought: ${trader.buy('JAVA')}
Very nice!
Included in the EL MR is another feature that is related to method invocation,
namely that of customization of method invocations with the use of custom
ELResolvers. The default behavior for method calls, such as
#{trader.buy('JAVA')} is to look for the method buy, using reflection,
in the bean trader. This default behavior can be altered with custom
ELResovler. A new method invoke is thus added to ELResolver and this
method is used to resolve the evaluation of method calls in expressions,
much like the method getValue is used to resolve the evaluation of
properties in expressions. By providing custom ELResolvers, one can
make "calls" to methods that are not in the bean class. In a sense, this
feature enables the definition and invocation of macros, and can lead to some interesting
applications.
The default behavior for method calls is handled by the class
javax.el.BeanELResolver. Using reflection, it looks up the method in the bean class.
Currently overloaded methods are not supported, and the number of arguments
specified in the EL expression must matched that in the method signature.
This is so because we don't want to specify complicated overload resolution
rules in the EL specification.
However, the method ELResolver.invoke has a paramTypes argument that can be
used to specify the formal parameter types for the method. If this argument
is non-null, then the method with the same name and parameter types will be
selected for invocation. Although the EL syntax does not allow the
specification of parameter types in the method call, it can be done quite
easily with an extended syntax. Borrowing from Javascript (I think) one
can write, for instance
#{trader['buy(java.lang.String)']('JAVA')}
to indicate a call to the method buy with String argument. This is
currently not included in the MR, but if there are enough interest, it can
be considered for the next version of the specification.
The source for the changes to EL api and implementation can be found from Unified Expression Language project. The basic functionalities have been implemented. The area that needs further work is in the overloaded method resolution, and performance.
Posted at 10:42AM Feb 03, 2009 by kchung in Sun | Comments[5]
Posted by Ed Burns's Blog on February 04, 2009 at 01:17 PM PST #
Wow this is great news! I thought it was going to be overlooked in EE 6.
Posted by Ryan de Laplante on February 04, 2009 at 02:01 PM PST #
Cool. How I've wanted to do this on my facelet and it never worked. But I'm confused about one thing.
Spring Web Flow uses JBoss EL, and I'm able to invoke a method expression
trader.buy('JAVA')
in a flow definition file (as an SWF expression perhaps), but can't do the same on my facelet. Why the difference? How come it works in a flow definition but not in a facelet?
Posted by Edem Morny on February 05, 2009 at 01:21 AM PST #
Great news. Will ease the development and maintenance considerably.
Posted by rainwebs on February 05, 2009 at 04:18 AM PST #
This is truly excellent. I'm glad to see this much focus on reduction of code (faster evelopment), and usability! Keep up the great work! I'm REALLY looking forward to this.
Posted by Lincoln on February 06, 2009 at 08:23 AM PST #