EL Function Parameters with JBoss ELPosted by Roger Keays, 26 July 2008, 4:00 PM |
One of the current missing features of Unified EL as used in JSF is the lack of support for calling methods on an object. You can access a bean's properties that have getters and setters and get elements from a map by name, but cannot call simple functions like ${list.size()}or ${colours.RGBtoHex(0,75,50)}. The clever folks at JBoss built an EL implementation which adds this basic feature, and a recent thread on the JSR 314 mailing list prompted me to add it to our stack.
It's quite easy to do, and you don't have to install Seam. First, you need to download the JBoss EL implementation and add it to your build. Using maven, first add the jar to your repository:
$ mvn install:install-file -Dfile=jboss-el-2.0.1.GA.jar -DgroupId=org.jboss.el \
-DartifactId=jboss-el -Dversion=2.0.1 -Dpackaging=jar
Then add the dependency it to your pom:
<dependency> <groupId>org.jboss.el</groupId> <artifactId>jboss-el</artifactId> <version>2.0.1</version> <scope>compile</scope> </dependency>
And configure web.xml to use the new library:
<!-- jboss el expressions allow method params --> <context-param> <param-name>com.sun.faces.expressionFactory</param-name> <param-value>org.jboss.el.ExpressionFactoryImpl</param-value> </context-param>
That's all there is to it! The library is 100% backwards compatible with the stock EL implementation which is pretty handy. Also, it looks like the key features will make their way into JSF 2.0 :)
Some references for you:
- Chapter from Seam documentation describing JBoss EL
- JBoss EL subversion repo
- JBoss EL 2.0.1 download
| << Unix | Back to Blog | Packaging Your Facelets in JARs >> |
Comment posted by: Jose Noheda on 26 July 2008, 9:05 PM
Great to know. I was using CGLIB to mimic this behavior till now so I'll try it. But the article is a little bit lacking IMHO. Does this work with Facelets? Do we need to replace other libs? Does it work with MyFaces? And RichFaces? Portlets? I'm guessing some responses here but you could have done a better job.
Comment posted by: Pete Muir on 26 July 2008, 10:27 PM
Good post Roger, nice to see some interest in this under promoted project :-)
Jose: It works with Facelets, you don't need to replace other libs, it will work with MyFaces i they have a way of replacing the expression factory (the context parameter shown is RI specific), it works with RichFaces (of course!) and I know for sure it works with JBoss Portal via the Portlet bridge.
Comment posted by: Roger Keays on 29 July 2008, 4:11 PM
I couldn't find anything in the MyFaces docs about changing the EL Factory. You might have to ask on their mailing list about that.
Comment posted by: Nicholas Hagen on 6 August 2008, 9:55 PM
I actually did this same exact thing myself for my own projects in order to invoke methods from managed beans. However, I also added support for (1) variable arguments and (2) polymorphism.
For variable arguments, you can define a method such as public double avg(int... values) within a managed bean and then invoke it from an EL expression such as #{bean.avg(1, 2, 3, 4, 5)} and have it return 3.0. I also added this to the standard EL functions so you could have an EL function mapped to a variable argument java method and invoke #{f:avg(1, 2, 3)}. This works for any JDK. For JDK 5 you just map your methods with Type... params and with JDK 4 and older, you just map with Type[] params. I think this is a feature that would be nice to add to the JBoss EL impl.
In terms of polymorphism and some of this is already supported by standard EL and maybe even the JBoss EL, but I allow you to invoke a method/function and it tries to find the best match within that bean class or its super classes. Thus, you can have methods like: String getName(String prefix) and String getName(int prefix) and depending on the evaluated types of the EL params, it will pick the most appropriate method. This even works with the variable argument support, so you could also have a method named getName(double... values).
Anyways, it would be interesting to get these features maybe added/merged into the JBoss EL. If anyone is interested, let me know.
Nicholas Hagen
nicholas dot hagen at znetdevelopment dot com
Comment posted by: Roger Keays on 6 August 2008, 10:37 PM
Hey Nicholas, thanks for the comment. Sounds like some pretty handy features. I forwarded your message to the JSR314 expert group. /me bookmarks this thought.
Comment posted by: Ken on 16 August 2008, 2:42 AM
Do I have to use Maven to manage and build the project to utilize the Jboss EL lib?
Is there any other way?
Comment posted by: Ken on 16 August 2008, 2:52 AM
If I just add the Jboss El jar to my web app's lib folder, and when I tried to deploy the war to Glassfish v2 ur2, it says:
Unable to instantiate ExpressionFactory 'org.jboss.el.ExpressionFactoryImpl'
Exception sending context initialized event to listener instance of class com.sun.faces.config.ConfigureListener
com.sun.faces.config.ConfigurationException: It appears the JSP version of the container is older than 2.1 and unable to locate the EL RI expression factory, com.sun.el.ExpressionFactoryImpl. If not using JSP or the EL RI, make sure the context initialization parameter, com.sun.faces.expressionFactory, is properly set.
I did set the web.xml to use "org.jboss.el.ExpressionFactoryImpl".
Any help is greatly appreciated.
Comment posted by: Roger Keays on 16 August 2008, 4:00 AM
You shouldn't need maven. Are you using JSP or Facelets? I haven't tried this with JSP, although the docs indicate that it should work with JSP 2.0:
Comment posted by: Ken on 16 August 2008, 6:31 AM
I am using facelets 1.1.14 with JSF 1.2 RI 1.2_09.
The target app server is Glassfish v2 ur2, which is Java EE 5 compatible.
Java EE 5 requires both JSF 1.2 and JSP 2.1.
Facelets works fine in this server.
Comment posted by: Rafael Ponte on 31 August 2008, 3:21 PM
Great post Roger!
I tried to use JBoss EL with Tomcat 6.0.x, but I didn't get success. Do you know to say if JBoss EL works with Tomcat? Is necessary others jars in the project?
Cheers.
Comment posted by: Roger Keays on 31 August 2008, 4:17 PM
Hi Rafael,
I'm using this with Tomcat 6.0. You'll probably still need el-api.jar. I also have commons-el-1.0.jar, but I think that was to satisfy some other library.
Comment posted by: Rafael Ponte on 1 September 2008, 2:20 AM
Hi Roger,
I'm using Tomcat 6.0.18, JSF1.2 (Mojarra) and Facelets 1.1, but seen that the org.jboss.el.ExpressionFactoryImpl doesn't work. When I open a page with any EL as #{bean.list.size()} occurs an error, the expression is not evaluate.
com.sun.facelets.tag.TagAttributeException: /pages/departamentos.xhtml @21,60 value="#{depBean.departamentos.size()}" Error Parsing: #{depBean.departamentos.size()}[...]
at com.sun.facelets.tag.TagAttribute.getValueExpression(TagAttribute.java:259)
at com.sun.facelets.tag.jsf.ValueHolderRule$DynamicValueExpressionMetadata.applyMetadata(ValueHolderRule.java:101)Caused by: javax.el.ELException: Error Parsing: #{depBean.departamentos.size()}[...]
at org.apache.el.lang.ExpressionBuilder.createNodeInternal(ExpressionBuilder.java:125)
at org.apache.el.lang.ExpressionBuilder.build(ExpressionBuilder.java:146)Caused by: org.apache.el.parser.ParseException: Encountered "size(" at line 1, column 25.
Was expecting:
<IDENTIFIER> ...
at org.apache.el.parser.ELParser.generateParseException(ELParser.java:2129)
The Tomcat 6.0 already have el-api.jar in the his /lib directory, hence I think that I won't need it in my project, in the project has the el-ri.jar and jboss-el-2.0.1.GA.jar at /WEB-INF/lib/, but the application doesn't work yet!
Do you have any idea about my problem?
Comment posted by: Rafael Ponte on 1 September 2008, 2:59 AM
Hi Roger, I discovered the problem :) The problem was on the JSF Mojarra version, I was using mojarra 1.2_04 and because this occured the problem, seems that the version 1.2_04 have a bug. I change for version 1.2_05-b06-FCS getting success to works my application with jboss EL.
Thanks.
Comment posted by: Gaurav Arora on 11 April 2009, 7:30 PM
Thanks, works like a charm.
Comment posted by: Jean on 13 May 2009, 10:19 PM
I am having the same problam that Ken had...
Add a comment
Please visit http://www.ninthavenue.com.au/blog/el-function-parameters-with-jboss-el to add your comments.